Enforce mTLS PoP minimum binding strength for Managed Identity (#6049 Phase 2)#6059
Open
Robbie-Microsoft wants to merge 2 commits into
Open
Enforce mTLS PoP minimum binding strength for Managed Identity (#6049 Phase 2)#6059Robbie-Microsoft wants to merge 2 commits into
Robbie-Microsoft wants to merge 2 commits into
Conversation
…Phase 2) Add PoPOptions with a MinStrength floor and a managed identity WithMtlsProofOfPossession(PoPOptions) overload. When MinStrength is greater than None, the token request runs host capability discovery and fails fast with MsalError.MinStrengthNotMet if the host's maximum binding strength is below the requested floor. The parameterless overload now delegates to the new overload with a default (None) floor. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Include MtlsPopMinStrength in the managed identity token cache key so a higher-floor request cannot be satisfied from a cache entry created by a lower/no-floor request, closing a latent gap where the MinStrength floor (enforced only on the acquisition path) could be bypassed on a cache hit. Mirrors the existing attestation-mode cache partitioning. Adds a regression test proving a KeyGuard-floor request does not reuse a no-floor token entry. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Implements Phase 2 of the Managed Identity (MI) mTLS Proof-of-Possession (PoP) work by introducing a public PoPOptions type with a minimum required MtlsBindingStrength floor (MinStrength) and enforcing that floor during MI token acquisition via capability discovery. The change also ensures token cache partitioning includes the requested minimum strength, preventing higher-floor requests from reusing lower/no-floor cache entries.
Changes:
- Added
PoPOptions(public API) and a new MI overloadWithMtlsProofOfPossession(PoPOptions), with the parameterless overload delegating to it. - Enforced
PoPOptions.MinStrengthat request time by running MI host capability discovery and failing fast withMsalError.MinStrengthNotMetwhen the host max strength is below the requested floor. - Partitioned the MI token cache key by minimum strength (
mi_minstrength) and added unit tests covering floor behavior and cache partitioning.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| tests/Microsoft.Identity.Test.Unit/ManagedIdentityTests/ImdsV2Tests.cs | Adds unit tests covering min-strength floors (met/not met), default behavior, null options, and cache-key partitioning. |
| src/client/Microsoft.Identity.Client/PublicApi/netstandard2.0/PublicAPI.Unshipped.txt | Declares new public APIs (PoPOptions, MinStrengthNotMet, MI PoP overload) for netstandard2.0. |
| src/client/Microsoft.Identity.Client/PublicApi/net8.0/PublicAPI.Unshipped.txt | Declares new public APIs for net8.0. |
| src/client/Microsoft.Identity.Client/PublicApi/net8.0-ios/PublicAPI.Unshipped.txt | Declares new public APIs for net8.0-ios. |
| src/client/Microsoft.Identity.Client/PublicApi/net8.0-android/PublicAPI.Unshipped.txt | Declares new public APIs for net8.0-android. |
| src/client/Microsoft.Identity.Client/PublicApi/net472/PublicAPI.Unshipped.txt | Declares new public APIs for net472. |
| src/client/Microsoft.Identity.Client/PublicApi/net462/PublicAPI.Unshipped.txt | Declares new public APIs for net462. |
| src/client/Microsoft.Identity.Client/MsalErrorMessage.cs | Adds formatted error message text for the min-strength-not-met failure. |
| src/client/Microsoft.Identity.Client/MsalError.cs | Adds new public error code MinStrengthNotMet. |
| src/client/Microsoft.Identity.Client/ManagedIdentity/ManagedIdentityPopExtensions.cs | Adds WithMtlsProofOfPossession(PoPOptions) overload and delegates parameterless overload to it; plumbs MinStrength. |
| src/client/Microsoft.Identity.Client/ManagedIdentity/ManagedIdentityClient.cs | Enforces the min-strength floor via capability discovery before proceeding with MI token acquisition. |
| src/client/Microsoft.Identity.Client/Internal/Requests/AuthenticationRequestParameters.cs | Exposes MtlsPopMinStrength from common parameters to request parameters. |
| src/client/Microsoft.Identity.Client/AppConfig/PoPOptions.cs | Introduces the new public options class and documents MinStrength semantics. |
| src/client/Microsoft.Identity.Client/ApiConfig/Parameters/AcquireTokenForManagedIdentityParameters.cs | Adds MtlsPopMinStrength to MI request parameters and logs it. |
| src/client/Microsoft.Identity.Client/ApiConfig/Parameters/AcquireTokenCommonParameters.cs | Adds MtlsPopMinStrength to common parameters (set by MI PoP options). |
| src/client/Microsoft.Identity.Client/ApiConfig/AcquireTokenForManagedIdentityParameterBuilder.cs | Plumbs MtlsPopMinStrength into MI parameters and partitions the MI cache key by min strength. |
| src/client/Microsoft.Identity.Client.KeyAttestation/ManagedIdentityAttestationExtensions.cs | Updates XML cref to point at the correct WithMtlsProofOfPossession overload signature. |
Contributor
|
This PR needs a little more detailed description or a task to understand the requirements better. |
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.
Summary
Implements Phase 2 of #6049: enforces a minimum mTLS Proof-of-Possession (PoP) binding-strength floor for Managed Identity (MI).
A caller can now require that the host be able to produce at least a given binding strength; when the host cannot meet the floor the request fails fast. This is a floor assertion, not a downgrade selector — MSAL always uses the host's maximum binding strength.
Scope is MI only; confidential-client support is deferred.
Public API
PoPOptionsclass (AppConfig) withMtlsBindingStrength MinStrength(defaultNone= no floor).WithMtlsProofOfPossession(PoPOptions); the parameterless overload now delegates to it (platform/NET462 guards preserved).MsalError.MinStrengthNotMet.PublicAPI.Unshipped.txtupdated for all 6 TFMs.Behavior
MtlsPopMinStrengthis plumbed through the common/MI parameters and exposed on the request parameters.None,ManagedIdentityClient.SendTokenRequestForManagedIdentityAsyncruns host capability discovery and throwsMinStrengthNotMet(message names the host's actual strength and the required floor) if the host's max binding strength is below the floor. No-op whenNone.mi_minstrength) so a higher-floor request cannot be served from a lower/no-floor cache entry (mirrors the existing attestation-mode partitioning).Tests
ImdsV2Tests.cs: floor met (KeyGuard/Software on KeyGuard host), defaultNonebehaves like parameterless, floor not met →MinStrengthNotMet, nullPoPOptions→ArgumentNullException, and a cache-key partitioning regression (higher-floor request does not reuse a no-floor token).TreatWarningsAsErrors.Notes
Software(Phase 1 behavior), so aSoftwarefloor passes the check and the request then fails withMtlsPopTokenNotSupportedinImdsV1rather than a single coherent reason. The request fails either way.