Skip to content

Fix credential scope normalization for AzureCLICredential in CI#91

Merged
arusso-aboutcloud merged 1 commit into
mainfrom
fix-role-fetcher-credential-scope
May 20, 2026
Merged

Fix credential scope normalization for AzureCLICredential in CI#91
arusso-aboutcloud merged 1 commit into
mainfrom
fix-role-fetcher-credential-scope

Conversation

@arusso-aboutcloud
Copy link
Copy Markdown
Owner

Root cause

`DefaultAzureCredential` falls through to `AzureCLICredential` after `azure/login` OIDC (earlier credential types — `EnvironmentCredential`, `WorkloadIdentityCredential`, `ManagedIdentityCredential` — all fail on GitHub-hosted runners without extra env-var plumbing). `AzureCLICredential` calls `az account get-access-token` and passes the scope string as a resource identifier. A delegated-permission scope like `https://graph.microsoft.com/RoleManagement.Read.Directory\` causes `AADSTS500011` because the CLI treats the full path as the resource `appId` — no such resource exists in Entra.

The Phase 1 sanity-check worked because it passed `https://graph.microsoft.com/.default\` directly. Phase 2 passes `collector.GraphRoleManagementReadScope` (`https://graph.microsoft.com/RoleManagement.Read.Directory\`), which breaks the CLI credential path.

Fix

Extract a `normalizeScope` helper and call it in `credAdapter.Token` before passing scopes to `DefaultAzureCredential.GetToken`. The helper converts:

`AzureCLICredential` then strips `/.default` to extract the resource URL (`https://graph.microsoft.com\`) and calls `az account get-access-token --resource https://graph.microsoft.com\`, which succeeds against the `azure/login` session.

Test plan

  • `TestNormalizeScopes` covers the three cases above
  • `go test ./...` green
  • `gofmt -l .` empty
  • CI passes
  • After merge: trigger `workflow_dispatch` — expect "Wrote N roles to data/roles_catalog.json" and a commit back to main

🤖 Generated with Claude Code

DefaultAzureCredential falls through to AzureCLICredential after azure/login
OIDC. That credential passes the scope string to az account get-access-token
as a resource identifier, so a delegated-permission scope like
https://graph.microsoft.com/RoleManagement.Read.Directory triggers AADSTS500011
because the CLI treats the full path as the resource appId.

Normalize each scope to its resource's .default form before calling GetToken.
AzureCLICredential then strips /.default to extract the correct resource URL
and the token request succeeds.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@arusso-aboutcloud arusso-aboutcloud merged commit 08b76d9 into main May 20, 2026
9 checks passed
@arusso-aboutcloud arusso-aboutcloud deleted the fix-role-fetcher-credential-scope branch May 20, 2026 13:16
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.

1 participant