Skip to content

Allow Azure Arc managed identity requests to forward user-assigned identity selectors - #944

Merged
Gladwin Johnson (gladjohn) merged 17 commits into
devfrom
copilot/azure-arc-uami-support
Aug 11, 2026
Merged

Allow Azure Arc managed identity requests to forward user-assigned identity selectors#944
Gladwin Johnson (gladjohn) merged 17 commits into
devfrom
copilot/azure-arc-uami-support

Conversation

Copilot AI commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Azure Arc now previews user-assigned managed identity support. This change aligns MSAL Python with that behavior by removing the Arc-only rejection path and forwarding the selected identity on Arc token requests.

  • Azure Arc request flow

    • Remove the Azure Arc guard that rejected UserAssignedManagedIdentity.
    • Thread managed_identity into _obtain_token_on_arc(...).
    • Apply Arc-specific selector mapping on both the challenge request and the authenticated request:
      • client_id
      • mi_res_id
      • object_id
  • Parameter mapping

    • Use the existing _adjust_param(...) helper with an explicit Arc/App Service-style mapping so resource IDs are sent as mi_res_id rather than the default resource_id.
  • Tests

    • Replace the Arc “user-assigned not supported” expectation with Arc happy-path coverage for:
      • client_id
      • resource_idmi_res_id
      • object_id
    • Assert the selector is present on both Arc HTTP calls.
params = {"api-version": "2020-06-01", "resource": resource}
_adjust_param(params, managed_identity, types_mapping={
    ManagedIdentity.CLIENT_ID: "client_id",
    ManagedIdentity.RESOURCE_ID: "mi_res_id",
    ManagedIdentity.OBJECT_ID: "object_id",
})

Copilot AI requested review from Copilot and removed request for Copilot July 15, 2026 23:47
Copilot AI changed the title [WIP] [DO NOT MERGE] Add support for user-assigned managed identity in MSAL Python [DO NOT MERGE] Allow Azure Arc managed identity requests to forward user-assigned identity selectors Jul 15, 2026
@gladjohn
Gladwin Johnson (gladjohn) marked this pull request as ready for review July 16, 2026 02:24
@gladjohn
Gladwin Johnson (gladjohn) requested a review from a team as a code owner July 16, 2026 02:24
Copilot AI lite review requested due to automatic review settings July 16, 2026 02: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

This PR updates the Azure Arc managed identity flow in MSAL Python to allow forwarding user-assigned identity selectors (client ID, resource ID, object ID) instead of rejecting user-assigned managed identities on Arc. It threads the managed_identity input into the Arc request path and maps resource_id to Arc/App Service’s expected wire name mi_res_id for both the challenge and authenticated HTTP calls.

Changes:

  • Remove the Arc-only rejection of UserAssignedManagedIdentity and pass managed_identity into _obtain_token_on_arc(...).
  • Add Arc-specific selector parameter mapping (including resource_idmi_res_id) on both Arc HTTP requests.
  • Update tests to validate selectors are forwarded for Arc user-assigned MI (client_id, mi_res_id, object_id) on both Arc calls.

Reviewed changes

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

File Description
msal/managed_identity.py Allows Arc MI token acquisition to include user-assigned selector parameters (with Arc-specific mapping) on both Arc HTTP calls.
tests/test_mi.py Replaces the “user-assigned not supported on Arc” expectation with happy-path tests asserting selector forwarding on both Arc requests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 593fce2a-8559-422e-92e2-46fb29c251a4
Copilot AI review requested due to automatic review settings July 16, 2026 14:36

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 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread msal/sku.py Outdated
Copilot AI review requested due to automatic review settings July 16, 2026 18:09

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 4 out of 4 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings July 16, 2026 18:27
Copilot AI review requested due to automatic review settings July 16, 2026 21:05

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 4 out of 4 changed files in this pull request and generated 3 comments.

Comment thread .Pipelines/pipeline-publish.yml
Comment thread .Pipelines/pipeline-publish.yml Outdated
Comment thread .Pipelines/pipeline-publish.yml
Copilot AI review requested due to automatic review settings July 16, 2026 21:29

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 4 out of 4 changed files in this pull request and generated 2 comments.

Comment thread .Pipelines/pipeline-publish.yml Outdated
Comment thread .Pipelines/pipeline-publish.yml
@bgavrilMS

Copy link
Copy Markdown
Member

Gladwin Johnson (@gladjohn) - is this one review-able now?

Live testing against the Azure Connected Machine agent (1.67, user-assigned preview)
showed the Arc token endpoint only honors the IMDS 'msi_res_id' spelling for the
resource-id selector; 'mi_res_id' is silently ignored and returns the system-assigned
identity, so a resource-id UAMI never resolved. Forward 'msi_res_id' on the Arc request
(matching the VM/IMDS source). Update the unit test accordingly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5ad57850-7d1f-4b9a-bf9f-723d69a9687c
Copilot AI review requested due to automatic review settings August 10, 2026 19:58
…e Arc MI

The publish-pipeline edits (BuildDist Linux->Windows pool, python -m build ->
setup.py, dropped twine check, Windows-style artifact paths on Linux pools) are
unrelated to the Azure Arc managed identity selector forwarding this PR targets and
were flagged in review as non-deterministic and broken on Linux. Restore
.Pipelines/pipeline-publish.yml to the dev baseline so those concerns are removed and
the PR only carries the Arc change.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5ad57850-7d1f-4b9a-bf9f-723d69a9687c

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 3 out of 3 changed files in this pull request and generated no new comments.

Suppressed comments (1)

msal/managed_identity.py:650

  • The Arc selector mapping uses msi_res_id for ManagedIdentity.RESOURCE_ID, but the PR description/example says Arc should send resource IDs as mi_res_id. Please confirm which spelling Arc actually honors and align either the code/tests or the PR description/release notes so consumers aren’t misled.
        _adjust_param(params, managed_identity, types_mapping={
            ManagedIdentity.CLIENT_ID: "client_id",
            ManagedIdentity.RESOURCE_ID: "msi_res_id",  # Azure Arc honors the IMDS msi_res_id spelling; mi_res_id is ignored and returns the system-assigned identity
            ManagedIdentity.OBJECT_ID: "object_id",
        })

Copilot AI review requested due to automatic review settings August 10, 2026 20:02

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 3 out of 3 changed files in this pull request and generated no new comments.

Suppressed comments (1)

msal/managed_identity.py:650

  • PR description says Arc should map user-assigned resource_id to the mi_res_id query param, but the implementation (and tests) use msi_res_id. Please align the PR description and implementation: either update the PR description/snippet to msi_res_id (if this is correct for Arc HIMDS), or switch this mapping (and the tests) to mi_res_id if that was the intended behavior.
    params = {"api-version": "2020-06-01", "resource": resource}
    if managed_identity:
        _adjust_param(params, managed_identity, types_mapping={
            ManagedIdentity.CLIENT_ID: "client_id",
            ManagedIdentity.RESOURCE_ID: "msi_res_id",  # Azure Arc honors the IMDS msi_res_id spelling; mi_res_id is ignored and returns the system-assigned identity
            ManagedIdentity.OBJECT_ID: "object_id",
        })

@gladjohn Gladwin Johnson (gladjohn) changed the title [DO NOT MERGE] Allow Azure Arc managed identity requests to forward user-assigned identity selectors Allow Azure Arc managed identity requests to forward user-assigned identity selectors Aug 10, 2026
Comment thread msal/managed_identity.py
…ed identity

Mirrors the response verification already present in MSAL .NET
(VerifyUserAssignedIdentityWasHonored) and Go (verifyAzureArcUserAssignedIdentity),
addressing review feedback that the Python PR only forwarded the selector without
verifying the token response.

A legacy Azure Arc agent ignores the client_id/object_id/msi_res_id selector and
silently returns the machine's system-assigned identity. After a 200, compare the
echoed identity (client_id/object_id/msi_res_id; mi_res_id accepted as a safety net)
to the requested selector and raise ManagedIdentityError if missing or mismatched, so
MSAL never returns a token for a different identity than the one requested.
System-assigned is unaffected. Existing UAMI forwarding tests now echo the identity;
added a fail-closed test.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5ad57850-7d1f-4b9a-bf9f-723d69a9687c
Copilot AI review requested due to automatic review settings August 10, 2026 22:21

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 3 out of 3 changed files in this pull request and generated no new comments.

Suppressed comments (1)

msal/managed_identity.py:676

  • The wire name for ResourceId on Azure Arc is set to msi_res_id, but the PR description/example refers to mi_res_id. Please reconcile the naming (either update the PR description/example and test naming to msi_res_id, or switch the Arc mapping to mi_res_id if that is actually the intended/required Arc parameter) to avoid confusing consumers and future maintainers.
    params = {"api-version": "2020-06-01", "resource": resource}
    if managed_identity:
        _adjust_param(params, managed_identity, types_mapping={
            ManagedIdentity.CLIENT_ID: "client_id",
            ManagedIdentity.RESOURCE_ID: "msi_res_id",  # Azure Arc honors the IMDS msi_res_id spelling; mi_res_id is ignored and returns the system-assigned identity
            ManagedIdentity.OBJECT_ID: "object_id",
        })

Copilot AI review requested due to automatic review settings August 11, 2026 14:16

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 3 out of 3 changed files in this pull request and generated no new comments.

Suppressed comments (2)

msal/managed_identity.py:676

  • The Arc selector mapping passed to _adjust_param duplicates ManagedIdentity._types_mapping (client_id/object_id/msi_res_id). Keeping a second hard-coded mapping here adds drift risk and makes it harder to reason about which mapping is authoritative. Prefer relying on the shared default mapping and keep the Arc-specific note as a comment.
    if managed_identity:
        _adjust_param(params, managed_identity, types_mapping={
            ManagedIdentity.CLIENT_ID: "client_id",
            ManagedIdentity.RESOURCE_ID: "msi_res_id",  # Azure Arc honors the IMDS msi_res_id spelling; mi_res_id is ignored and returns the system-assigned identity
            ManagedIdentity.OBJECT_ID: "object_id",

msal/managed_identity.py:665

  • When Azure Arc does not echo back the requested selector, the exception message doesn’t include which selector was requested nor what value was echoed. Including those details would make it much easier to diagnose whether the agent ignored the selector vs. returned a different identity.
    if not echoed or str(echoed).lower() != str(requested).lower():
        raise ManagedIdentityError(
            "Azure Arc did not confirm the requested user-assigned managed identity "
            "in the token response. The agent likely does not support user-assigned "
            "managed identities and returned the system-assigned identity.")

@gladjohn
Gladwin Johnson (gladjohn) merged commit 711d8a6 into dev Aug 11, 2026
8 checks passed
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.

6 participants