fix: accept legacy Azure Resource Manager audience in JWT validation - #203
fix: accept legacy Azure Resource Manager audience in JWT validation#203rootsecdev wants to merge 1 commit into
Conversation
|
All contributors have signed the CLA ✍️ ✅ |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
Walkthrough
ChangesAudience normalization
Estimated code review effort: 2 (Simple) | ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
🔧 Fix failing CI
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
I have read the CLA Document and I hereby sign the CLA |
Problem
--jwt fails with failed to create new Azure client: error: invalid token audience when supplied an ARM access token whose aud claim is https://management.core.windows.net/ rather than https://management.azure.com.
Entra ID issues ARM tokens under either of two registered identifier URIs, and ARM accepts both. ParseAud only trims a trailing slash, so client/client.go:52 and client/rest/auth.go:299 compare the legacy URI against the canonical endpoint and reject a valid token.
az account get-access-token resolves the ARM scope through activeDirectoryResourceId, which is https://management.core.windows.net/ for AzureCloud. Tokens sourced from the Azure CLI including from Cloud Shell, where the token proxy normalizes to that resource ID regardless of the requested scope are rejected outright. Requesting --scope https://management.azure.com/.default explicitly does not reliably change the resulting audience.
Fix
Normalize the legacy identifier URI to the canonical endpoint inside ParseAud. Both audience checks client selection at startup and per-request validation call ParseAud, so a single normalization covers initialization and every outbound request. Without this, a token could pass startup and then fail mid-collection.
Equivalent legacy URIs for US Gov and China are included for parity.
Scope
Only audiences that ARM already treats as equivalent are affected. Any other audience, including Graph, passes through unchanged, so no previously rejected token becomes accepted except the ARM aliases.
Testing
Added client/rest/utils_test.go covering the alias normalization (with and without trailing slash, all three clouds), trailing-slash trimming, unchanged passthrough for Graph and an unrelated audience, and the malformed-token error path.
Verified end-to-end against a real tenant: azurehound list az-rm --jwt with a management.core.windows.net audience fails on main and completes collection with this change. go build ./... and go test ./... pass.
Bonus
Testing and confirming fix through an Azure Cloud Shell session was a bonus as this can evade conditional access policies.
Summary by CodeRabbit