Skip to content

Add WithRequestOverMtls() API and E2E test: attested bearer via IMDSv2 mTLS flow - #6086

Merged
Gladwin Johnson VR (gladjohn) merged 10 commits into
mainfrom
copilot/add-e2e-test-bearer-token-fallback
Aug 7, 2026
Merged

Gladwin Johnson VR (gladjohn) merged 10 commits into
mainfrom
copilot/add-e2e-test-bearer-token-fallback

Conversation

Copilot AI commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Adds a new public API WithMtlsBearerToken() that uses the full IMDSv2 attested mTLS flow (Credential Guard–issued certificate, mTLS connection to ESTS) but requests token_type=bearer, returning a standard bearer token with no binding certificate. Also adds the corresponding E2E test.

Changes proposed in this request

  • Added WithMtlsBearerToken() extension method to ManagedIdentityPopExtensions.cs (Windows-only, mirrors WithMtlsProofOfPossession() but sends token_type=bearer to ESTS instead of token_type=mtls_pop)
  • Plumbed IsMtlsBearerRequested flag through AcquireTokenCommonParameters, AcquireTokenForManagedIdentityParameters, AuthenticationRequestParameters, AcquireTokenForManagedIdentityParameterBuilder, ManagedIdentityAuthRequest, and AbstractManagedIdentity
  • Updated routing in ManagedIdentityClient to route IsMtlsBearerRequested to IMDSv2 (same as IsMtlsPopRequested)
  • Extended the KeyGuard validation in ImdsV2ManagedIdentitySource.CreateRequestAsync to cover both PoP and ****** under a unified credential_guard_not_available error code
  • Added a separate cache partition for mTLS-bearer tokens (mtls_bearer key component) to keep them distinct from PoP tokens and plain IMDSv1 bearer tokens
  • Updated PublicAPI.Unshipped.txt for all target frameworks
  • Replaced the original AcquireToken_OnImdsV2_WithAttestation_NoMtlsPoP_ReturnsBearer E2E test with AcquireToken_OnImdsV2_WithMtlsBearerToken_ReturnsBearer, which calls .WithMtlsBearerToken().WithAttestationSupport() and asserts TokenType == "Bearer", BindingCertificate == null, absence of the cnf claim in the JWT payload, and TokenSource == IdentityProvider
  • Updated unit test error code assertion to credential_guard_not_available
var result = await mi.AcquireTokenForManagedIdentity(GraphResource)
    .WithMtlsBearerToken()      // uses IMDSv2 attested flow, token_type=bearer
    .WithAttestationSupport()   // adds Credential Guard attestation JWT
    .ExecuteAsync()
    .ConfigureAwait(false);

Assert.AreEqual("Bearer", result.TokenType);
Assert.IsNull(result.BindingCertificate);
var jwt = new JwtSecurityToken(result.AccessToken);
Assert.IsFalse(jwt.Payload.ContainsKey("cnf"));
Assert.AreEqual(TokenSource.IdentityProvider, result.AuthenticationResultMetadata.TokenSource);

Testing
Updated E2E test uses .WithMtlsBearerToken() and runs on the MSALMSIV2 pool (Credential Guard / VBS enabled). Gracefully marks inconclusive if Credential Guard is unavailable. Unit test for the KeyGuard-not-available error path updated to match the new unified error code.

Performance impact
None.

Documentation

  • All relevant documentation is updated.

Copilot AI requested review from Copilot and removed request for Copilot June 23, 2026 17:38
Copilot AI changed the title [WIP] Add E2E test for Bearer token fallback on IMDSv2 Add E2E test: ****** when WithMtlsProofOfPossession() is omitted on IMDSv2 host Jun 23, 2026
@gladjohn Gladwin Johnson VR (gladjohn) changed the title Add E2E test: ****** when WithMtlsProofOfPossession() is omitted on IMDSv2 host Add E2E test: Get Bearer when WithMtlsProofOfPossession() is omitted on IMDSv2 host - Still need CVM/TVM + KeyGuard Jun 23, 2026
@gladjohn
Gladwin Johnson VR (gladjohn) marked this pull request as ready for review June 23, 2026 18:30
@gladjohn
Gladwin Johnson VR (gladjohn) requested a review from a team as a code owner June 23, 2026 18:30
Copilot AI lite review requested due to automatic review settings June 23, 2026 18:30
@gladjohn
Gladwin Johnson VR (gladjohn) marked this pull request as draft June 23, 2026 18:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an end-to-end regression test in the Managed Identity IMDSv2 E2E suite to validate that when .WithMtlsProofOfPossession() is omitted (even if .WithAttestationSupport() is present), MSAL returns a standard Bearer token (no binding certificate) on an IMDSv2-capable host.

Changes:

  • Added a new [DataRow]-driven E2E test covering SAMI and UAMI (clientId) scenarios for the “no mTLS PoP requested” path.
  • Asserts Bearer token shape (TokenType == "Bearer", BindingCertificate == null) and that the token was acquired from the identity provider.

Comment thread tests/Microsoft.Identity.Test.E2e/ManagedIdentityImdsV2Tests.cs
@gladjohn

Copy link
Copy Markdown
Contributor

We will need a new Bearer API to support this e2e

Comment thread tests/Microsoft.Identity.Test.E2e/ManagedIdentityImdsV2Tests.cs Outdated
Copilot AI requested review from Copilot and removed request for Copilot June 25, 2026 19:18
Copilot AI changed the title Add E2E test: Get Bearer when WithMtlsProofOfPossession() is omitted on IMDSv2 host - Still need CVM/TVM + KeyGuard Add WithMtlsBearerToken() API and E2E test: Get attested ****** via IMDSv2 mTLS flow Jun 25, 2026
@gladjohn

Copy link
Copy Markdown
Contributor

Copilot resolve conflicts

This was referenced Sep 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants