Azure / Azure/azure-sdk-for-python

[Identity] Support Azure Arc user-assigned managed identity (UAMI) via MSAL

Open
#48,708 0 comments 1 reaction 2 assignees Claimed by @kashifkhan View on GitHub
Azure.Identity feature-request
Dominant language
Python
Stars
5.6k
Forks
3.4k
Avg merge
1d 21h
Merged PRs (30d)
193

Description

## Background

MSAL Python now supports acquiring tokens for **user-assigned managed identities (UAMI) on Azure Arc** (MSAL Python **1.38.0**). Historically Azure Arc only supported system-assigned managed identity (SAMI). This issue tracks enabling Arc UAMI in `azure-identity` (`ManagedIdentityCredential` and `DefaultAzureCredential`), for both sync and async.

`azure-identity` has **two independent managed-identity stacks** for Arc, and they need different work:

## Current behavior

- **Sync (MSAL)** `AzureArcCredential` (`azure/identity/_credentials/azure_arc.py`) extends `MsalManagedIdentityClient` and delegates to `msal.ManagedIdentityClient` (`acquire_token_for_client`, `msal.UserAssignedManagedIdentity` / `SystemAssignedManagedIdentity`). UAMI-on-Arc is gated by MSAL, so a **`msal` version bump is sufficient** here.
- **Async (native, no MSAL)** `AzureArcCredential` (`azure/identity/aio/_credentials/azure_arc.py`) extends `AsyncManagedIdentityBase` and drives the custom `AsyncManagedIdentityClient` (`aio/_internal/managed_identity_client.py`, built on `build_async_pipeline`) plus `ArcChallengeAuthPolicy`. **MSAL Python is sync-only, so the async path cannot delegate to MSAL and will NOT inherit Arc UAMI from the dependency bump** — it needs its own code change.
- **Explicit block:** `_get_request` in `_credentials/azure_arc.py` (imported and used by the async credential) raises `ClientAuthenticationError("User assigned managed identities are not supported by Azure Arc...")` whenever `identity_config` is set. `ManagedIdentityClientBase.__init__` folds `client_id` into `self._identity_config`, so this trips for client id, object id, and resource id. This block is effectively **async-only** now (the sync credential goes through MSAL and no longer calls `_get_request`).

Net effect: **sync** needs only a dependency uptake; **async (native)** needs the explicit block removed, the id sent as the correct query parameter, and behavior aligned with the MSAL/sync path.

## Scope of work

### Sync (MSAL)
- [x] Bump `msal` dependency to `>= 1.38.0`.
- [ ] Verify Arc UAMI token acquisition (client id, and resource/object id as supported).

### Async (native, no MSAL)
- [x] Remove the explicit UAMI-on-Arc block in `_get_request` (`_credentials/azure_arc.py`).
- [ ] Send the user-assigned id as the correct Arc query parameter — map the `resource_id` key to the Arc param name (`mi_res_id`/`msi_res_id`); `client_id`/`object_id` names are already correct. Confirm the `api-version` (currently `2020-06-01`) honors UAMI and matches what MSAL sends on the sync side.
- [ ] (Alternative) Consider delegating the async path to MSAL via `run_in_executor` for behavioral parity with sync, instead of maintaining the native implementation (larger change; adds thread-pool overhead).
- [ ] Update async tests (e.g. `test_azure_arc*` / aio variants) that currently assert Arc UAMI is rejected.

### Shared
- [ ] Keep sync (MSAL) and async (native) consistent on query-param names, api-version, and endpoint handling.
- [ ] Update CHANGELOG (and README if it documents Arc as system-assigned-only).

## Key references

- `sdk/identity/azure-identity/azure/identity/_credentials/azure_arc.py`
- `sdk/identity/azure-identity/azure/identity/aio/_credentials/azure_arc.py`
- `sdk/identity/azure-identity/azure/identity/aio/_internal/managed_identity_client.py`
- `sdk/identity/azure-identity/azure/identity/_internal/managed_identity_client.py`
- `sdk/identity/azure-identity/azure/identity/_internal/msal_managed_identity_client.py`

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.