Add polling options, service endpoint, CBOR error handling, and SDK updates#168
Merged
elantiguamsft merged 12 commits intomainfrom Mar 13, 2026
Merged
Add polling options, service endpoint, CBOR error handling, and SDK updates#168elantiguamsft merged 12 commits intomainfrom
elantiguamsft merged 12 commits intomainfrom
Conversation
…, and SDK updates MstPollingOptions tunable receipt polling: - PollingInterval (TimeSpan?) for fixed-interval polling - DelayStrategy (Azure.Core.DelayStrategy?) for custom back-off - DelayStrategy takes precedence if both are set; null = SDK default TransparencyService.ServiceEndpoint base class URI property: - Auto-derived from CodeTransparencyClient via reflection - Explicit URI override via constructor parameter RFC 9290 CBOR problem details parsing: - CborProblemDetails: parses integer keys (-1..-5) + string keys + extensions - MstServiceException: FromRequestFailedException() parses CBOR error bodies - MakeTransparentCoreAsync catches RequestFailedException with structured errors Azure.Core.TestCommon test infrastructure: - MockResponse, MockTransport, MockRequest, etc. ported from azure-sdk-for-net - Enables testing Azure SDK clients with controlled responses Azure SDK package updates: - Azure.Core 1.50.0 -> 1.51.1 - Azure.Identity 1.17.0 -> 1.18.0 - Azure.Security.CodeTransparency 1.0.0-beta.5 -> 1.0.0-beta.8 Tests: 92 pass, 0 fail (51 new). Coverage on new code: CborProblemDetails.cs 94.9% MstPollingOptions.cs 100% MstServiceException.cs 96.9%
- Seal MockRequest and MockResponse to prevent virtual call issues in ctors - Replace generic catch clauses with specific CborContentException, InvalidOperationException, TargetInvocationException in production code - Use ternary expressions in DictionaryHeaders for cleaner assignment - Remove unused variable in CborProblemDetailsTests - Add System.Formats.Cbor using to MstServiceException - All 92 MST tests pass Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Fix naming: rename _serviceEndpoint to ServiceEndpointUri (PascalCase) - Add HalfPrecisionFloat handling in CborProblemDetails.ReadAnyValue - Fix test: assert on ex.Message and ProblemDetails in BuildErrorMessage test - Add test: MakeTransparentAsync wraps RequestFailedException in MstServiceException - Fix comment: update Azure.Core version reference to 1.51.1 - All 93 MST tests pass (1 new) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…nt retries - Custom Azure SDK pipeline policy that handles 503/TransactionNotCached with aggressive 250ms retries (up to 8 attempts) instead of server's 1-second Retry-After header - CBOR problem details body parsed to verify TransactionNotCached error code - Policy is scoped: only GET /entries/ 503s are retried; all other requests pass through to the SDK's normal retry infrastructure - Extension method ConfigureTransactionNotCachedRetry() on CodeTransparencyClientOptions - ToCoseSign1TransparencyService() overload accepting MstPollingOptions - CodeTransparencyClientHelper now configures the policy by default - RegisterCommand and VerifyCommand now use 250ms LRO polling interval - Removed unused CtsCommandBase and CtsCommandBaseLoggingTests - Updated documentation with new extension methods and retry behavior
Replace auto-property overrides with explicit backing fields in MockRequest and MockResponse so constructors assign fields directly instead of invoking virtual property setters. Both classes are sealed so the original code was safe at runtime, but CodeQL still flags the pattern. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Replace foreach+if with LINQ .Any() for cleaner extension value filtering - Replace bare catch with catch (Exception) to satisfy generic-catch-clause alert Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace catch (Exception) with IOException, ObjectDisposedException, and NotSupportedException to satisfy CodeQL generic-catch-clause alert. CborProblemDetails.TryParse already handles CBOR exceptions internally, so only stream I/O failures need catching here. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add missing using directives in doc code snippets (Azure.Core, Azure.Core.Pipeline) - Dispose previous Response before retry in MstTransactionNotCachedPolicy - Replace single Stream.Read with CopyTo for reliable body buffering - Move BinaryDataExtensions from System to CoseSign1.Transparent.MST namespace - Align TryGetMstEntryId docs with actual behavior (returns empty string, not null) - Update MstPollingOptions DelayStrategy docs to describe WaitForCompletionAsync overload - Make pollingOptions parameter nullable in MstTransparencyService constructors - Fix CHANGELOG version tag: v.1.5.5 -> v1.5.5 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Added using statement to bodyBuffer MemoryStream in TryGetEntryIdFromBody to ensure proper disposal. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
elantiguamsft
previously approved these changes
Mar 12, 2026
- Link RFC 9290 citations as hyperlinks in CborProblemDetails XML docs - Add descriptive comments explaining Response disposal before retry - Pass CancellationToken to Task.Delay; add ThrowIfCancellationRequested for sync path - Extract DefaultPollingIntervalMs constant in MstCommandBase (used by Register/Verify) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
elantiguamsft
approved these changes
Mar 12, 2026
JosephSchutzMSFT
approved these changes
Mar 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Performance: Fast retry policy, tunable polling, structured error handling, and SDK updates
Motivation
The Azure Code Transparency service returns
503 TransactionNotCachedwhen a newly registered entry hasn't propagated to the read replicas yet — typically resolved in well under 1 second. However, the server'sRetry-After: 1header causes the SDK's default retry logic to wait a full second between attempts, adding unnecessary latency to the hot path of entry registration and receipt retrieval. This PR eliminates that bottleneck and adds several supporting features.🚀
MstTransactionNotCachedPolicy— Fast 503 retry pipeline policy (new)A custom
HttpPipelinePolicythat intercepts503 TransactionNotCachedresponses and performs aggressive, in-pipeline retries before the SDK's standard retry logic kicks in.retryDelaymaxRetriesHow it works:
HTTP 503+GETmethod + URI path contains/entries/+ CBOR body withTransactionNotCachederror codeKey design decisions:
HttpPipelinePosition.PerRetry— runs inside the SDK's retry loop, minimizing total latencyConfiguration via extension method:
⏱️
MstPollingOptions— Tunable receipt polling (new)Controls how
MakeTransparentAsyncpolls for the long-running operation receipt.PollingIntervalTimeSpan?DelayStrategyDelayStrategy?null→ SDK default exponential back-offPollingIntervalset →WaitForCompletionAsync(interval, ct)DelayStrategyset →Operation<T>.DelayStrategyassignment (overridesPollingInterval)RegisterCommandandVerifyCommandnow default to 250ms fixed polling📋
CborProblemDetails— RFC 9290 Concise Problem Details parser (new)Parses CBOR-encoded error responses per RFC 9290:
TypeTitleStatusDetailInstanceExtensionsAlso accepts string keys (
"type","title", etc.) for interoperability. HandlesHalfPrecisionFloatCBOR values consistent withCwtClaims.cs.🔥
MstServiceException— Structured error wrapping (new)Wraps
Azure.RequestFailedExceptionwith parsed CBOR problem details:Content-Typeforcbor, extracts and parses the response bodyToString()includes all parsed fields and extensions for diagnostics🔌
TransparencyService.ServiceEndpoint— Base class URI property (new)CodeTransparencyClientvia reflection (best-effort)TransparencyServiceimplementations📦 Azure SDK package updates
Azure.CoreAzure.IdentityAzure.Security.CodeTransparency🧪
Azure.Core.TestCommon— Test infrastructure (new)Vendored from azure-sdk-for-net test infrastructure (Azure.Core 1.51.1 era):
MockResponse,MockTransport,MockRequest— controlled HTTP responses for testing Azure SDK clientsAsyncGate,AsyncValidatingStream,DictionaryHeaders— supporting utilities[ExcludeFromCodeCoverage]🗑️ Removed
CtsCommandBase(332 lines) andCtsCommandBaseLoggingTests(482 lines) — superseded by the new polling and retry infrastructureTest coverage
MstTransactionNotCachedPolicyMstPollingOptionsMstTransparencyServiceoverloadsCborProblemDetailsHalfPrecisionFloatMstServiceExceptionFromRequestFailedException,BuildErrorMessage,ToString,StatusCodeMstTransparencyServiceMakeTransparentAsyncwrapsRequestFailedExceptioninMstServiceExceptionSummary for reviewers
The core performance improvement is the
MstTransactionNotCachedPolicy— by retrying at 250ms instead of the server's 1-secondRetry-After, entry receipt retrieval that previously took 2–4 seconds now typically completes in under 1 second. Combined with 250ms LRO polling intervals (replacing SDK default exponential back-off), end-to-end registration latency is significantly reduced.All new code has structured CBOR error handling, cancellation token support, and comprehensive test coverage.