Skip to content

Add GetManagedIdentityCapabilitiesAsync host capability discovery API (Phase 1)#6049

Merged
Robbie-Microsoft merged 7 commits into
mainfrom
rginsburg/GetManagedIdentityCapabilitiesAsync
Jun 4, 2026
Merged

Add GetManagedIdentityCapabilitiesAsync host capability discovery API (Phase 1)#6049
Robbie-Microsoft merged 7 commits into
mainfrom
rginsburg/GetManagedIdentityCapabilitiesAsync

Conversation

@Robbie-Microsoft

@Robbie-Microsoft Robbie-Microsoft commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements Phase 1 of the GetManagedIdentityCapabilitiesAsync proposal (spec: PR #6040) to unblock the AKV SDK. Builds on Bogdan's #6026 (/metadata/instance/compute host detection, validated on a real VM) rather than starting fresh.

This is the discovery API only. The WithMtlsProofOfPossession(PoPOptions { MinStrength }) enforcement knob is Phase 2 / follow-up and is intentionally out of scope.

What changed

  • New public API ManagedIdentityApplication.GetManagedIdentityCapabilitiesAsync(CancellationToken) returning ManagedIdentityCapabilities (Source, ErrorReason, MaxSupportedBindingStrength, derived IsMtlsPopSupportedByHost).
  • New MtlsBindingStrength enum in Microsoft.Identity.Client.AppConfig (Bearer=0, Software=1, KeyGuard=3; 2 reserved for a future TPM tier), shared by MI and confidential-client mTLS PoP.
  • Strength detection:
    • IMDSv2-success path probes the platform key provider — a VBS-isolated KeyGuard key reports the attested KeyGuard tier, otherwise the Software floor (mirrors what the v2 PoP token flow requires).
    • IMDSv1-only path uses the /compute security profile (TVM/CVM → Software, else Bearer).
    • Bearer on .NET Framework 4.6.2 (no PoP).
  • Folded ManagedIdentitySource.ImdsV2 back into Imds — the v1/v2 distinction is now internal routing only; callers branch on the capability signal.
  • Removed the old GetManagedIdentitySourceAsync + ManagedIdentitySourceResult; updated PublicAPI.Shipped.txt / PublicAPI.Unshipped.txt across all TFMs.

Semantics (per the approved spec)

IsMtlsPopSupportedByHost is derived (MaxSupportedBindingStrength > Bearer) and means "the host can bind a token to a key" — NOT "attested." Attestation must be read from the KeyGuard tier specifically. Documented in the XML docs.

Capability discovery may provision/persist a binding key on capable hosts as a side effect, pre-warming the cache reused by a later token request (documented on the API).

Safety for AKS / high-density hosts

AKS nodes are Linux with no TVM/CVM profile, so IsMtlsPopSupportedByHost comes back false; Azure SDK also gates on FEDERATED_TOKEN_FILE before calling MSAL's MI path.

Tests

Covers AKS/Linux → IsMtlsPopSupportedByHost = false, Windows TVM/CVM IMDSv2 → KeyGuard tier, IMDSv2 software-key → Software, and existing token flows unchanged. Builds clean across all TFMs (TreatWarningsAsErrors); ManagedIdentity / ImdsV2 / AppService unit suites green.

Out of scope (Phase 2 follow-up)

PoPOptions + WithMtlsProofOfPossession(PoPOptions) minimum-strength enforcement, and MsalError.MinStrengthNotMet. Not needed for the AKV unblock.

Robbie-Microsoft and others added 3 commits June 2, 2026 15:44
Builds on #6026's compute-metadata detection to ship the capability-discovery API agreed in the #6040 proposal:

- Add GetManagedIdentityCapabilitiesAsync(CancellationToken) on ManagedIdentityApplication returning ManagedIdentityCapabilities (Source, MaxSupportedBindingStrength, derived IsMtlsPopSupportedByHost); remove GetManagedIdentitySourceAsync/ManagedIdentitySourceResult.
- Add public MtlsBindingStrength enum (Bearer/Software/KeyGuard) in AppConfig.
- Port ComputeMetadataResponse + ImdsComputeMetadataManager from #6026; register JSON types.
- Fold public ManagedIdentitySource.ImdsV2 into Imds while preserving internal v1/v2 routing; gate MSIv1 claims validation behind RequiresMsiV1ClaimsValidation.
- Discovery maps IMDSv2 success to Software and IMDSv1 success to compute-metadata-derived strength (TVM/CVM Windows to Software, else Bearer).
- Update all 6 TFM PublicAPI files, tests, and changelog.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The IMDSv2-success path now probes the platform managed-identity key
provider and advertises the attested KeyGuard tier when a VBS-isolated
KeyGuard key is obtainable, mirroring what the v2 PoP token flow itself
requires. It floors at Software (never downgrades a confirmed v2 host)
and reports Bearer on net462. The IMDSv1-only compute-based path is
unchanged and renamed for clarity.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
GetManagedIdentityCapabilitiesAsync may provision and persist a binding
key while detecting the strongest available binding strength on capable
hosts, pre-warming the cache reused by a later token request.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Robbie-Microsoft Robbie-Microsoft requested a review from a team as a code owner June 2, 2026 20:56
Copilot AI review requested due to automatic review settings June 2, 2026 20:56

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

This PR implements Phase 1 of managed identity host capability discovery by introducing a new public discovery API (GetManagedIdentityCapabilitiesAsync) that reports the detected managed identity source plus the host’s maximum supported mTLS binding strength (via the new MtlsBindingStrength enum). It also folds the public ManagedIdentitySource.ImdsV2 enum value back into Imds and updates tests and public API baselines accordingly.

Changes:

  • Added ManagedIdentityApplication.GetManagedIdentityCapabilitiesAsync(CancellationToken) returning ManagedIdentityCapabilities (Source, ErrorReason, MaxSupportedBindingStrength, derived IsMtlsPopSupportedByHost).
  • Added Microsoft.Identity.Client.AppConfig.MtlsBindingStrength and IMDS compute-metadata fetching to infer binding strength (IMDSv1 via /compute, IMDSv2 via key provider probing).
  • Removed the legacy GetManagedIdentitySourceAsync/ManagedIdentitySourceResult API surface and updated PublicAPI baselines across TFMs; updated unit tests to match the new discovery flow.

Reviewed changes

Copilot reviewed 32 out of 32 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/Microsoft.Identity.Test.Unit/ManagedIdentityTests/ManagedIdentityTests.cs Updates discovery tests to use GetManagedIdentityCapabilitiesAsync and adds binding-strength assertions for IMDS scenarios.
tests/Microsoft.Identity.Test.Unit/ManagedIdentityTests/ImdsV2Tests.cs Reworks IMDSv2 tests to validate the new discovery API and to inject deterministic key providers before capability discovery.
tests/Microsoft.Identity.Test.Unit/ManagedIdentityTests/AppServiceTests.cs Switches App Service upgrade test to the new discovery API.
src/client/Microsoft.Identity.Lab.Api/Http/MockHelpers.cs Adds mock handlers for IMDS compute metadata (/metadata/instance/compute) including 200 and 404 responses.
src/client/Microsoft.Identity.Lab.Api/Helpers/ManagedIdentityTestUtil.cs Removes ImdsV2 from test environment-variable routing (now folded into Imds).
src/client/Microsoft.Identity.Client/PublicApi/netstandard2.0/PublicAPI.Unshipped.txt Adds new public types/members (MtlsBindingStrength, ManagedIdentityCapabilities, GetManagedIdentityCapabilitiesAsync).
src/client/Microsoft.Identity.Client/PublicApi/netstandard2.0/PublicAPI.Shipped.txt Removes ManagedIdentitySource.ImdsV2 and the legacy ManagedIdentitySourceResult/GetManagedIdentitySourceAsync API surface.
src/client/Microsoft.Identity.Client/PublicApi/net8.0/PublicAPI.Unshipped.txt Same PublicAPI additions for net8.0.
src/client/Microsoft.Identity.Client/PublicApi/net8.0/PublicAPI.Shipped.txt Same PublicAPI removals for net8.0.
src/client/Microsoft.Identity.Client/PublicApi/net8.0-ios/PublicAPI.Unshipped.txt Same PublicAPI additions for net8.0-ios.
src/client/Microsoft.Identity.Client/PublicApi/net8.0-ios/PublicAPI.Shipped.txt Same PublicAPI removals for net8.0-ios.
src/client/Microsoft.Identity.Client/PublicApi/net8.0-android/PublicAPI.Unshipped.txt Same PublicAPI additions for net8.0-android.
src/client/Microsoft.Identity.Client/PublicApi/net8.0-android/PublicAPI.Shipped.txt Same PublicAPI removals for net8.0-android.
src/client/Microsoft.Identity.Client/PublicApi/net472/PublicAPI.Unshipped.txt Same PublicAPI additions for net472.
src/client/Microsoft.Identity.Client/PublicApi/net472/PublicAPI.Shipped.txt Same PublicAPI removals for net472.
src/client/Microsoft.Identity.Client/PublicApi/net462/PublicAPI.Unshipped.txt Same PublicAPI additions for net462.
src/client/Microsoft.Identity.Client/PublicApi/net462/PublicAPI.Shipped.txt Same PublicAPI removals for net462.
src/client/Microsoft.Identity.Client/Platforms/net/MsalJsonSerializerContext.cs Registers new IMDS compute metadata DTOs for System.Text.Json source generation.
src/client/Microsoft.Identity.Client/ManagedIdentityApplication.cs Replaces GetManagedIdentitySourceAsync with GetManagedIdentityCapabilitiesAsync and wires it to the new internal discovery result.
src/client/Microsoft.Identity.Client/ManagedIdentity/V2/ImdsV2ManagedIdentitySource.cs Updates IMDSv2 source reporting to ManagedIdentitySource.Imds (public v1/v2 fold).
src/client/Microsoft.Identity.Client/ManagedIdentity/V2/CertificateRequestResponse.cs Updates managed identity source attribution in error construction (v1/v2 fold).
src/client/Microsoft.Identity.Client/ManagedIdentity/ManagedIdentitySourceResult.cs Removes the legacy public result type for source discovery.
src/client/Microsoft.Identity.Client/ManagedIdentity/ManagedIdentitySource.cs Removes the public ImdsV2 enum member and updates the obsolete message for DefaultToImds.
src/client/Microsoft.Identity.Client/ManagedIdentity/ManagedIdentityDiscoveryResult.cs Adds internal discovery result carrying public source + internal IMDS protocol version + binding strength + probe failure reasons.
src/client/Microsoft.Identity.Client/ManagedIdentity/ManagedIdentityClient.cs Implements new discovery flow, caches discovery result, and adds IMDSv1/v2 binding-strength detection.
src/client/Microsoft.Identity.Client/ManagedIdentity/ManagedIdentityCapabilities.cs Adds the new public capabilities DTO (source, error reason, max binding strength, derived PoP support flag).
src/client/Microsoft.Identity.Client/ManagedIdentity/ImdsManagedIdentitySource.cs Introduces IMDSv1-specific claims validation flag to preserve behavior after folding IMDS v1/v2 into a single public source label.
src/client/Microsoft.Identity.Client/ManagedIdentity/ImdsComputeMetadataManager.cs Adds /metadata/instance/compute call and helper to infer host PoP capability from OS/security profile.
src/client/Microsoft.Identity.Client/ManagedIdentity/ComputeMetadataResponse.cs Adds DTOs for compute metadata response (osType, securityProfile.securityType).
src/client/Microsoft.Identity.Client/ManagedIdentity/AbstractManagedIdentity.cs Preserves IMDSv1-only claim validation via a new virtual flag, now that IMDS v1/v2 share the same public source label.
src/client/Microsoft.Identity.Client/AppConfig/MtlsBindingStrength.cs Adds new public enum describing binding strength tiers (Bearer, Software, KeyGuard).
CHANGELOG.md Documents the new discovery API and the folding/removal of the legacy discovery surface.

Comment thread src/client/Microsoft.Identity.Client/ManagedIdentity/ManagedIdentityClient.cs Outdated
Comment thread CHANGELOG.md Outdated
Comment thread src/client/Microsoft.Identity.Client/ManagedIdentity/ManagedIdentityClient.cs Outdated
Comment thread src/client/Microsoft.Identity.Client/ManagedIdentity/ManagedIdentityClient.cs Outdated
…gelog link

- Serialize GetManagedIdentityCapabilitiesAsync with a static SemaphoreSlim so concurrent first calls don't issue redundant IMDS probes or provision the binding key more than once (non-blocking fast-path acquire preserves the existing HTTP-probe cancellation point).
- Remove 'MSAL' from the IMDS-unavailable error message.
- Enrich the mtls_pop_requires_keyguard message with actionable VBS/KeyGuard guidance (error code unchanged).
- Fix CHANGELOG entry to link this PR (#6049) instead of the proposal (#6040).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Robbie-Microsoft Robbie-Microsoft requested a review from gladjohn June 3, 2026 19:04
Comment thread src/client/Microsoft.Identity.Client/AppConfig/MtlsBindingStrength.cs Outdated
…cancellation handling

Addresses review feedback on PR #6049:
- MtlsBindingStrength floor renamed Bearer -> None (strength tier, not a
  token type); reworded XML docs and updated PublicAPI.Unshipped baselines.
- Collapsed the explicit OperationCanceledException rethrow into an exception
  filter on the broad catch in ImdsComputeMetadataManager.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 4, 2026 16:13

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

Copilot reviewed 33 out of 33 changed files in this pull request and generated 2 comments.

Comment thread CHANGELOG.md Outdated
Comment thread issue6046_check.txt Outdated
Robbie-Microsoft and others added 2 commits June 4, 2026 12:22
Addresses Copilot review feedback on PR #6049:
- Remove issue6046_check.txt, a design scratch note accidentally committed.
- Update CHANGELOG to reference the renamed MtlsBindingStrength.None value
  (was Bearer) so the documented API surface matches the code.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 4, 2026 16:24

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

Copilot reviewed 32 out of 32 changed files in this pull request and generated 1 comment.

@Robbie-Microsoft Robbie-Microsoft enabled auto-merge (squash) June 4, 2026 16:51
@Robbie-Microsoft Robbie-Microsoft merged commit 80b6ecc into main Jun 4, 2026
17 checks passed
@Robbie-Microsoft Robbie-Microsoft deleted the rginsburg/GetManagedIdentityCapabilitiesAsync branch June 4, 2026 16:52
This was referenced Jun 5, 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.

4 participants