Skip to content

Fix #6024: probe IMDSv2 first and remove preview latch#6041

Merged
Robbie-Microsoft merged 1 commit into
mainfrom
rginsburg/fix-6024-probe-order
May 29, 2026
Merged

Fix #6024: probe IMDSv2 first and remove preview latch#6041
Robbie-Microsoft merged 1 commit into
mainfrom
rginsburg/fix-6024-probe-order

Conversation

@Robbie-Microsoft

@Robbie-Microsoft Robbie-Microsoft commented May 28, 2026

Copy link
Copy Markdown
Contributor

Fixes #6024.

Problem

ManagedIdentityClient.GetManagedIdentitySourceAsync probed IMDSv1 first. By contract, IMDS returns HTTP 400 (the documented success signal for the probe) on the v1 token endpoint for every IMDS host — including v2-capable ones. As a result, v2-capable hosts were always cached as ImdsV1 and the Azure SDK mTLS PoP discovery path was unreachable end-to-end.

Fix

  1. Swap probe order: probe the IMDSv2 CSR metadata endpoint first; fall back to the IMDSv1 token endpoint only if v2 fails. The v2 CSR metadata path returns 404 on v1-only hosts (including AKS GPMD), so the fallback is correct.
  2. Delete the s_imdsV1UsedForPreview latch (and its CannotSwitchBetweenImdsVersionsForPreview throw). With v2-first discovery, this dormant latch would start firing on any process that performs a non-PoP MI call before a PoP MI call — the exact Azure SDK call pattern. The per-request IMDSv1 fallback for non-PoP requests is preserved, but no state is latched; subsequent PoP requests still route to the cached ImdsV2 source.

Backward compatibility

Tests

  • Flipped mock ordering in all existing ImdsV2Tests / ManagedIdentityTests probe call sites.
  • Repurposed ApplicationsCannotSwitchBetweenImdsVersionsForPreviewApplicationsCanSwitchBetweenImdsVersions: verifies non-PoP fallback followed by PoP request now succeeds (previously threw).
  • Full ManagedIdentity suite: 398 passed, 1 skipped (unrelated), 0 failed.

ManagedIdentityClient.GetManagedIdentitySourceAsync now probes the IMDSv2 CSR metadata endpoint before falling back to the IMDSv1 token endpoint. Previously v1 was probed first, and because the IMDS contract returns HTTP 400 (success signal) on every host for the v1 token path, v2-capable hosts were never detected and were always cached as ImdsV1. This broke the Azure SDK mTLS PoP discovery path end-to-end.

Also removes the dormant s_imdsV1UsedForPreview latch and its associated CannotSwitchBetweenImdsVersionsForPreview throw block. With v2-first discovery, that latch would have started firing on any process that performs a non-PoP MI call before a PoP MI call (the exact Azure SDK call pattern). Per-request IMDSv1 fallback for non-PoP requests is preserved without any state being latched, so subsequent PoP requests still route to the cached ImdsV2 source.

The MsalError.CannotSwitchBetweenImdsVersionsForPreview public constant is kept for backward compatibility (it ships in PublicAPI.Shipped.txt across all TFMs); only the throw site is removed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Robbie-Microsoft Robbie-Microsoft requested a review from a team as a code owner May 28, 2026 21:24
Copilot AI review requested due to automatic review settings May 28, 2026 21: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

Fixes managed identity IMDS discovery so IMDSv2-capable hosts are correctly detected and cached, enabling the managed-identity mTLS PoP path end-to-end (fix for #6024).

Changes:

  • Switched explicit IMDS discovery to probe IMDSv2 first and fall back to IMDSv1 only if v2 fails.
  • Removed the “preview latch” behavior that blocked switching from a prior non-PoP (v1 fallback) call to a later PoP (v2) call within the same process.
  • Updated unit tests and documentation to reflect the new probe order and mixed-usage behavior.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
src/client/Microsoft.Identity.Client/ManagedIdentity/ManagedIdentityClient.cs Probes IMDSv2 first during explicit discovery; removes the IMDSv1/preview latch throw while preserving per-request non-PoP fallback to v1.
tests/Microsoft.Identity.Test.Unit/ManagedIdentityTests/ManagedIdentityTests.cs Updates IMDS probe mock ordering to match v2-first discovery.
tests/Microsoft.Identity.Test.Unit/ManagedIdentityTests/ImdsV2Tests.cs Updates probe ordering and repurposes the “cannot switch versions” test to assert mixed non-PoP then PoP usage now succeeds.
docs/mtlspop_managed_identity.md Updates documentation to remove the “switch blocked” behavior and reflect per-request fallback semantics.

@Robbie-Microsoft Robbie-Microsoft merged commit c832249 into main May 29, 2026
17 checks passed
@Robbie-Microsoft Robbie-Microsoft deleted the rginsburg/fix-6024-probe-order branch May 29, 2026 18:57
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.

[Bug] GetSourceAsync caches the wrong IMDS source

5 participants