Repository navigation
Honor AZURE_CLIENT_ID in DefaultAzureCredential managed identity - #7520
Open
Hari (hasethuraman) wants to merge 1 commit into
Open
Hari (hasethuraman) wants to merge 1 commit into
Hari (hasethuraman) wants to merge 1 commit into
Conversation
Use the environment client ID for managed identity selection in the default credential chain while preserving standalone ManagedIdentityCredential behavior. Add selector regression tests and document the compatibility change. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 11d8863b-ee0a-4f8e-94c4-e63edc82546b Signed-off-by: Hariharan Sethuraman <srnhari@gmail.com>
|
Thank you for your contribution Hari (@hasethuraman)! We will review the pull request and get back to you soon. |
|
Azure Pipelines: Successfully started running 3 pipeline(s). 7 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Hari (hasethuraman)
marked this pull request as ready for review
October 30, 2026 15:13
Hari (hasethuraman)
requested review from
a team,
Larry Osterman (LarryOsterman),
Rick Winter (RickWinter),
Anton Kolesnyk (antkmsft) and
Jeff Fisher (xirzec)
as code owners
October 30, 2026 15:13
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
On Cloud Shell or Azure Arc, a non-empty AZURE_CLIENT_ID causes eager managed-identity construction to throw, preventing DefaultAzureCredential from using an otherwise working EnvironmentCredential.
1 open issue
What changed in this PR
This PR makes the Azure Identity default credential chain use AZURE_CLIENT_ID for managed identity selection, aligning its behavior with other Azure SDKs while leaving standalone constructors unchanged.
Changes:
- Pass the environment client ID to managed identity, including managed-identity-only chains.
- Add selector and standalone-behavior regression tests and update expected logs.
- Document configuration and compatibility implications.
| File | Description |
|---|---|
| sdk/identity/azure-identity/test/ut/default_azure_credential_test.cpp | Tests client-ID selection and unchanged standalone behavior; updates logs. |
| sdk/identity/azure-identity/src/default_azure_credential.cpp | Passes AZURE_CLIENT_ID to the chain’s managed identity credential. |
| sdk/identity/azure-identity/README.md | Explains environment-based managed identity selection. |
| sdk/identity/azure-identity/inc/azure/identity/default_azure_credential.hpp | Documents the updated default-chain behavior. |
| sdk/identity/azure-identity/CHANGELOG.md | Records the feature and compatibility change. |
Review effort: Balanced
Comment on lines
+101
to
+102
| return std::shared_ptr<ManagedIdentityCredential>(new ManagedIdentityCredential( | ||
| Environment::GetVariable("AZURE_CLIENT_ID"), !specificCred, options)); |
This branch has not been deployed
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
AZURE_CLIENT_IDwhenDefaultAzureCredentialconstructs the managed identity credential in its chain.ManagedIdentityCredentialconstructors unchanged.Motivation
On an Azure host with multiple user-assigned managed identities, IMDS can reject a token request without an identity selector. Setting
AZURE_CLIENT_IDcurrently does not select an identity for the C++ default chain's managed identity credential.This brings parity with the environment-based managed identity client-ID selection supported by
DefaultAzureCredentialin Python, .NET, Java, JavaScript/TypeScript, and Go:managed_identity_client_idfromAZURE_CLIENT_ID, then passes it toManagedIdentityCredential.DefaultAzureCredentialOptions.ManagedIdentityClientIddefaults toAZURE_CLIENT_ID.loadFallbackValuesFromEnvironment()readsAZURE_CLIENT_IDwhen no managed identity client ID is configured.createDefaultManagedIdentityCredential()falls back toprocess.env.AZURE_CLIENT_ID.AZURE_CLIENT_IDand passes it toManagedIdentityCredentialOptions.ID.This comparison is specifically about default-chain client-ID selection, not identical credential ordering, endpoint support, retry behavior, or standalone managed identity constructors.
The change also applies when
AZURE_TOKEN_CREDENTIALS=ManagedIdentityCredential; it does not change credential ordering or IMDS probe/retry configuration.Validation
prod, and managed-identity-only chains, plus unchanged standalone behavior.sudo; two recordedTokenCredentialTestcases failed because the playback proxy was unavailable. These four cases remain incomplete, not passing or skipped.git diff --checkpasses.Native application A/B check
Built otherwise-identical RunAI Model Streamer core/Azure wheels from unchanged application source, once with unpatched C++ Identity and once with this patch. Only the Azure native backend binary differed between wheel contents, excluding wheel
RECORDchecksums; Python files and the common native library were byte-identical.Ran
SafetensorsStreamer.stream_files([uri])against a public-model fixture in Azure Blob Storage on the same existing AKS CPU node:AZURE_CLIENT_IDAll successful cases consumed 272 tensors (269,030,016 payload bytes) and matched the known content fingerprint. Runtime native-library hashes matched the built artifacts.
The node case had no workload identity token, account key, SAS, client secret, credential-chain override, or DACS cache. No Python Azure SDK
download_blob()call substituted for native streaming.Compatibility review
This intentionally changes default-chain behavior when
AZURE_CLIENT_IDis non-empty: the managed identity credential now selects that identity instead of issuing an unselected request. Applications setting this variable for another credential may therefore observe different fallback behavior. Managed identity sources that reject user-assigned identity selectors also need compatibility review.Standalone managed identity credential construction remains explicit and unchanged. Opening as a draft for maintainer feedback on this behavior change.