Native agentic token for UserManagedIdentity via fmi_path exchange#448
Open
Hameedkunkanoor wants to merge 1 commit into
Open
Native agentic token for UserManagedIdentity via fmi_path exchange#448Hameedkunkanoor wants to merge 1 commit into
Hameedkunkanoor wants to merge 1 commit into
Conversation
MsalAuth.get_agentic_application_token raised RuntimeError for
AuthTypes.user_managed_identity because MSAL's ManagedIdentityClient does not
support the federated fmi_path exchange required for agentic application tokens.
Callers had to monkey-patch get_agentic_application_token to work around this.
This adds a native branch that, for user_managed_identity, acquires the token via
azure-identity's DefaultAzureCredential with identity_config={"fmi_path": ...}
(and managed_identity_client_id from CLIENT_ID when set) against the managed-
identity endpoints. azure-identity is imported lazily and a clear ImportError is
raised if it is not installed, so it stays an optional dependency.
- New MsalAuth._acquire_agentic_token_via_managed_identity helper.
- Updated the unsupported-client test to use system_managed_identity (still
raises); added a user_managed_identity test that injects a fake
DefaultAzureCredential (no azure-identity needed to run the test).
- black clean (libraries + tests); 30/30 msal_auth tests pass.
Note: complements microsoft#413 (identity_proxy_manager), which added a distinct IDPM
resource path but does not perform the fmi_path federated exchange.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds native support in MsalAuth.get_agentic_application_token for AuthTypes.user_managed_identity to acquire agentic application tokens via a federated fmi_path exchange using azure-identity’s async DefaultAzureCredential, eliminating the need for consumers to monkey-patch SDK behavior.
Changes:
- Added a
user_managed_identitybranch inget_agentic_application_tokenthat performs thefmi_pathexchange viaDefaultAzureCredentialagainstapi://AzureAdTokenExchange/.default. - Introduced
_acquire_agentic_token_via_managed_identityhelper with lazyazure-identityimport and best-effort credential cleanup. - Updated tests to (a) cover the new
user_managed_identitypath and (b) keep the “unsupported client” RuntimeError coverage by switching it tosystem_managed_identity.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| libraries/microsoft-agents-authentication-msal/microsoft_agents/authentication/msal/msal_auth.py | Adds user_managed_identity agentic token acquisition via DefaultAzureCredential + fmi_path exchange. |
| tests/authentication_msal/test_msal_auth.py | Adds a unit test for the user_managed_identity fmi_path exchange path and adjusts the unsupported-auth-type test. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+441
to
+456
| credential = DefaultAzureCredential(**credential_kwargs) | ||
| try: | ||
| token = await credential.get_token("api://AzureAdTokenExchange/.default") | ||
| return token.token | ||
| except Exception: # noqa: BLE001 - failures are logged and surfaced as None | ||
| logger.exception( | ||
| "Failed to acquire agentic application token via DefaultAzureCredential " | ||
| "for agent_app_instance_id=%s", | ||
| agent_app_instance_id, | ||
| ) | ||
| return None | ||
| finally: | ||
| try: | ||
| await credential.close() | ||
| except Exception: # noqa: BLE001 - best-effort cleanup | ||
| logger.debug("Error closing DefaultAzureCredential", exc_info=True) |
Comment on lines
+372
to
+375
| fake_module = types.ModuleType("azure.identity.aio") | ||
| fake_module.DefaultAzureCredential = _FakeCredential | ||
| mocker.patch.dict(sys.modules, {"azure.identity.aio": fake_module}) | ||
|
|
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
Adds native support to
MsalAuth.get_agentic_application_tokenfor acquiring an agentic application token whenAUTH_TYPEisAuthTypes.user_managed_identity, using the federatedfmi_pathexchange. Today this path raisesRuntimeError, forcing callers to monkey-patchget_agentic_application_token.Problem
For
AuthTypes.user_managed_identity,_create_client_applicationreturns an MSALManagedIdentityClient. MSAL'sManagedIdentityClientdoes not support the federatedfmi_pathtoken exchange required for agentic application tokens, soget_agentic_application_tokenfalls through toraise RuntimeErrorfor that auth type.In the Azure AI Foundry hosted-agent (digital-worker) model, the container is configured with
UserManagedIdentity, so consumers currently work around this by replacing the method at runtime:This proposal moves that logic into the SDK so no auth code is required from the developer.
Fix
Adds a branch to
get_agentic_application_token: foruser_managed_identityit acquires the token viaazure-identity'sDefaultAzureCredentialwithidentity_config={""fmi_path"": <agent_app_instance_id>}(andmanaged_identity_client_idfromCLIENT_IDwhen set) againstapi://AzureAdTokenExchange/.default.azure-identityis imported lazily and a clearImportErroris raised if it is not installed, so it stays an optional dependency.Relationship to #413
#413 added a distinct
AuthTypes.identity_proxy_manager(IDPM) path that does a direct managed-identityacquire_token_for_client(resource=...)call. That does not perform thefmi_pathfederated exchange the digital-worker model needs, and plainuser_managed_identitystill raised. This change complements #413 by covering theuser_managed_identity+fmi_pathcase natively.Testing
system_managed_identity(still correctly raisesRuntimeError).user_managed_identitytest that injects a fakeDefaultAzureCredentialviasys.modules(so it runs withoutazure-identityinstalled) and asserts thefmi_pathidentity_config, the managed_identity_client_id, the exchange scope, and credential cleanup.30/30tests intest_msal_auth.pypass;blackclean.