Summary
setup-entra-app.ps1 declares three Microsoft Graph / Log Analytics permission GUIDs that are not valid delegated (Scope) permissions. Because Entra validates a consent request atomically, admin consent fails for the entire app, and no service principal is created. Any fresh azd up into a tenant that requires admin consent is blocked at the "Connect Azure" step.
Affected code
src/Dashboard/setup-entra-app.ps1 (lines 138, 141, 145 — used as type = "Scope" on lines 163, 166, 172):
$graphOrgReadAll = "498476ce-e0fe-48b0-b801-37ba7e2685c6" # Organization.Read.All
$graphGroupReadAll = "5b567255-7703-4780-807c-7be8301ae99b" # Group.Read.All
$laDataRead = "e4aa47b9-9a69-4109-82ed-36ec70d85f3f" # Data.Read
Root cause
Two of the GUIDs are application role IDs (app-only permissions), not delegated scopes, yet they are declared as type = "Scope". The third does not exist on the Log Analytics API at all.
| Variable |
Current value |
What it actually is |
$graphOrgReadAll |
498476ce-... |
Organization.Read.All appRole (app-only) |
$graphGroupReadAll |
5b567255-... |
Group.Read.All appRole (app-only) |
$laDataRead |
e4aa47b9-... |
not present in Log Analytics oauth2PermissionScopes |
The script's own output text (lines 190–194) states these are intended to be delegated:
Log Analytics: Data.Read (delegated, read-only)
Microsoft Graph: ... (all delegated, read-only)
So the intent is delegated scopes; the values were taken from the appRole column.
Reproduction
azd up into a tenant where "Users can register applications" / user consent is restricted.
- Sign in, click Connect Azure.
- Entra shows "Need admin approval".
- A Global/Application Administrator grants consent — it silently fails.
az ad sp show --id <appId> → Resource does not exist (no service principal was ever created).
Verification
# Log Analytics API publishes exactly one delegated scope, and it is not e4aa47b9-...
az ad sp show --id ca7f3f0b-7d91-482c-8e09-c5d840d0eac5 `
--query "oauth2PermissionScopes[].{id:id,value:value}" -o json
# => [ { "id": "e8dac03d-d467-4a7e-9293-9cca7df08b31", "value": "Data.Read" } ]
# The two Graph GUIDs resolve as appRoles, not oauth2PermissionScopes
az ad sp show --id 00000003-0000-0000-c000-000000000000 `
--query "appRoles[?id=='498476ce-e0fe-48b0-b801-37ba7e2685c6'].value" -o tsv
# => Organization.Read.All
These are Microsoft first-party service principals, so the IDs are identical in every tenant — this is not environment-specific.
Proposed fix
-$graphOrgReadAll = "498476ce-e0fe-48b0-b801-37ba7e2685c6" # Organization.Read.All
+$graphOrgReadAll = "4908d5b9-3fb2-4b1e-9336-1888b7937185" # Organization.Read.All
-$graphGroupReadAll = "5b567255-7703-4780-807c-7be8301ae99b" # Group.Read.All
+$graphGroupReadAll = "5f8c59db-677d-491f-a6b8-5f174b11ec1d" # Group.Read.All
-$laDataRead = "e4aa47b9-9a69-4109-82ed-36ec70d85f3f" # Data.Read
+$laDataRead = "e8dac03d-d467-4a7e-9293-9cca7df08b31" # Data.Read
After applying this, every requested ID resolves against its resource's published oauth2PermissionScopes, and admin consent succeeds.
Secondary issue: silent failure of the redirect-URI patch
infra/scripts/postprovision.ps1 (line 40) patches the production redirect URI:
az ad app update --id $objectId --web-redirect-uris @merged --output none
In my run this left only http://localhost:5000/auth/microsoft/callback on the app registration — the https://<webHost>/auth/microsoft/callback entry was never added, which would have produced AADSTS50011 after consent. The script's fallback branch (line 45) prints a warning, but it scrolls past in normal azd up output.
Suggestion: fail loudly (non-zero exit) when the redirect-URI patch does not apply, or re-read and assert the URIs afterwards.
Suggested hardening
Rather than hardcoding GUIDs, resolve them at runtime so this class of bug cannot recur:
$laDataRead = az ad sp show --id $laAppId `
--query "oauth2PermissionScopes[?value=='Data.Read'].id" -o tsv
Environment
azd 1.25.6
- Azure CLI 2.83.0
- PowerShell 7.5.8 / Windows 11
- Repo
main as of commit 758c2c9
Summary
setup-entra-app.ps1declares three Microsoft Graph / Log Analytics permission GUIDs that are not valid delegated (Scope) permissions. Because Entra validates a consent request atomically, admin consent fails for the entire app, and no service principal is created. Any freshazd upinto a tenant that requires admin consent is blocked at the "Connect Azure" step.Affected code
src/Dashboard/setup-entra-app.ps1(lines 138, 141, 145 — used astype = "Scope"on lines 163, 166, 172):Root cause
Two of the GUIDs are application role IDs (app-only permissions), not delegated scopes, yet they are declared as
type = "Scope". The third does not exist on the Log Analytics API at all.$graphOrgReadAll498476ce-...Organization.Read.AllappRole (app-only)$graphGroupReadAll5b567255-...Group.Read.AllappRole (app-only)$laDataReade4aa47b9-...oauth2PermissionScopesThe script's own output text (lines 190–194) states these are intended to be delegated:
So the intent is delegated scopes; the values were taken from the appRole column.
Reproduction
azd upinto a tenant where "Users can register applications" / user consent is restricted.az ad sp show --id <appId>→Resource does not exist(no service principal was ever created).Verification
These are Microsoft first-party service principals, so the IDs are identical in every tenant — this is not environment-specific.
Proposed fix
After applying this, every requested ID resolves against its resource's published
oauth2PermissionScopes, and admin consent succeeds.Secondary issue: silent failure of the redirect-URI patch
infra/scripts/postprovision.ps1(line 40) patches the production redirect URI:In my run this left only
http://localhost:5000/auth/microsoft/callbackon the app registration — thehttps://<webHost>/auth/microsoft/callbackentry was never added, which would have producedAADSTS50011after consent. The script's fallback branch (line 45) prints a warning, but it scrolls past in normalazd upoutput.Suggestion: fail loudly (non-zero exit) when the redirect-URI patch does not apply, or re-read and assert the URIs afterwards.
Suggested hardening
Rather than hardcoding GUIDs, resolve them at runtime so this class of bug cannot recur:
Environment
azd1.25.6mainas of commit758c2c9