2.0.0 (2026-10-30)
Features Added
- Updated the client library to target the
2025-06-01Azure Attestation service API version. - Added
AttestationClientOptions.ServiceVersion.V2025_06_01, which is now the default service version.V2020_10_01remains available for callers that need to continue targeting the previous service API version. - Added the
AttestationType.AzureGuest,AttestationType.SevSnpVm, andAttestationType.TdxVmvalues.TdxVmrequires service versionV2025_06_01. - Added
AttestationClient.AttestTdxVmandAttestationClient.AttestSevSnpVm(and their async counterparts) to attest Intel TDX and AMD SEV-SNP confidential virtual machines.AttestTdxVmrequires service versionV2025_06_01;AttestationClient.CanAttestTdxVmindicates whether the client supports it. - Added
AttestationRequest.Nonce, which the service returns in thenonceclaim of the attestation token. - Added
AttestationResult.AdditionalClaims, which exposes the token's claims that have no dedicated property, such as the TDX and SEV-SNP claims and claims issued by attestation policy.AttestationModelFactory.AttestationResultaccepts them asadditionalClaimsfor mocking. - Added
AttestationClient.GetOpenIdMetadata(and its async counterpart), which retrieves the attestation provider's OpenID Connect discovery document as anAttestationOpenIdMetadata. - Added
AttestationClient.AttestAzureGuest(and its async counterpart) to attest Azure confidential and Trusted Launch virtual machines. It returns aSealedAttestationResultwhose token is encrypted to the virtual machine's TPM, so the client does not validate it. - Added
AttestationAdministrationClient.GetTcbBaselines(and its async counterpart), which lists the SGX trusted computing base (TCB) baselines an attestation policy can require, asTcbBaselineResultandTcbBaseline. It requires service versionV2025_06_01;AttestationAdministrationClient.CanGetTcbBaselinesindicates whether the client supports it. - Model types now implement
IJsonModel<T>andIPersistableModel<T>, andAzureSecurityAttestationContextwas added, for use withSystem.ClientModel.Primitives.ModelReaderWriter.
Breaking Changes
This release changes how attestation tokens are validated, so code that worked with 1.0.0 might need changes. See the migration guide for how to update it.
AttestationToken.ValidateTokenandAttestationToken.ValidateTokenAsyncnow returnfalsefor unsecured tokens, that is, tokens whosealgheader isnone. Such tokens carry no signature, so no signature verification was performed and validation previously succeeded by default. TheAttestationTokenValidationOptions.TokenValidatedhandler is no longer invoked for these tokens and cannot be used to accept them. Tokens returned by the Attestation service are signed and are unaffected, except for the response to an attestation request that setsDraftPolicyForAttestation: the service never signs it, so the client still returns it, as before, after checking its time claims and invoking theTokenValidatedhandler. Unsecured tokens sent to the service bySetPolicyandResetPolicyare also unaffected, as they are never validated by the client.- Attestation tokens are now validated against their issuer by default.
AttestationTokenValidationOptions.ValidateIssuerdefaults totrue, andAttestationClientandAttestationAdministrationClientuse their endpoint as the expected issuer whenExpectedIssueris not set. While issuer validation is enabled, a token without an issuer is rejected. Callers ofAttestationToken.ValidateTokenandAttestationToken.ValidateTokenAsyncmust setExpectedIssuerto the base URI of the attestation provider the token must come from, or setValidateIssuertofalse. AttestationToken.ValidateTokenandAttestationToken.ValidateTokenAsyncnow accept a signed token only if one of the signing certificates passed asattestationSigningCertificatessigned it. Previously, when no signing certificates were passed, the token was checked against the certificates in its own header. They now throwArgumentNullExceptionwhenattestationSigningCertificatesisnullandArgumentExceptionwhen it is empty; useAttestationClient.GetSigningCertificatesto retrieve the attestation provider's signing certificates. Certificates and keys in a token's header are no longer used to select a signer in any case.AttestationClientandAttestationAdministrationClientnow throwArgumentExceptionwhen the endpoint does not usehttps. AnAttestationClientcreated without a credential previously sent its requests, including the request for the certificates that validate tokens, without TLS.- When several handlers are attached to
AttestationTokenValidationOptions.TokenValidated, the token is now rejected if any of them setsIsValidtofalse. Previously only the value set by the last handler was used. AttestationTokenSigningKeynow throwsArgumentExceptionfor keys and certificates that are not RSA, such as ECDSA keys, instead ofNotSupportedExceptionorNullReferenceException. Only RSA signing keys are supported.AttestationTokenValidationOptions.TimeValidationSlacknow defaults to 5 seconds instead of 0. The service sets a token'snbfclaim with its own clock, which can be slightly ahead of the caller's, so with no slack a token returned by the service was intermittently rejected as not yet valid. SetTimeValidationSlackto 0 to restore exact time checks.
Bugs Fixed
- Fixed
GetPolicythrowing instead of returning a null policy when the requested attestation type has no policy configured. AttestationClient.GetSigningCertificatesAsync, which the async operations also use to fetch the keys that validate tokens, no longer makes a blocking network call.AttestationToken.ExpirationTime,NotBeforeTime, andIssuedAtTimeno longer truncate fractional seconds in the token'sexp,nbf, andiatclaims.- With a nonzero
AttestationTokenValidationOptions.TimeValidationSlack, token validation compared only the seconds component of the time elapsed sinceexp(or remaining untilnbf) with the slack, so a token outside the slack by a whole number of minutes could pass. It now compares the total elapsed time. AttestationToken.X509CertificateChainnow decodes the base64-encoded certificates in the token'sx5cheader on all target frameworks, and returns an empty array when the header has none. On .NET 9 and earlier, and on .NET Framework, it treated each entry as a file name, so it could not read the certificates in tokens returned by the service.AttestationAdministrationClient.SetPolicy,GetPolicyManagementCertificates, andGetPolicyManagementCertificatesAsyncno longer throw when aTokenValidatedhandler is attached; they now invoke it like the other operations.- A token without a
kidheader is now checked against every signing certificate passed toValidateTokenandValidateTokenAsync. Previously only the first was tried, so a token signed by another of them was rejected. - Tokens signed with an
AttestationTokenSigningKeynow carry the standard JWS algorithmRS256in theiralgheader, instead ofRSA256. - Tokens signed with an
AttestationTokenSigningKeycreated from a certificate alone now use the certificate's private key. Previously, on .NET 8 and later, signing failed with aCryptographicException. ValidateTokenandValidateTokenAsyncnow throwArgumentNullExceptionwhenoptionsisnullorattestationSigningCertificatescontainsnull, throwArgumentExceptionwhen one of the signers has no certificate, and returnfalsefor a token without analgheader, instead of throwingNullReferenceExceptionorArgumentOutOfRangeException.AttestationToken.ExpirationTime,NotBeforeTime, andIssuedAtTimenow returnDateTimeOffset.MaxValueorDateTimeOffset.MinValuefor claims outside the range ofDateTimeOffset, instead of throwingArgumentOutOfRangeException, so such tokens are validated against those values.
Other Changes
- Migrated the code generation from AutoRest/Swagger to TypeSpec.