Scope escalation through delegation
A chain of services each meant to narrow a token's authority instead widens it, because one hop in the delegation path trusts the scope a caller claims rather than the scope it was actually issued.
How it works
Scope escalation through delegation happens when a service that is supposed to pass on a narrower slice of a user's authority instead obtains, or accepts, a wider one. The resulting token carries more scope or audience than the delegation allowed, and nothing downstream can tell.
Modern architectures pass identity through several hops: a front end calls an API on the user's behalf, which calls another service. Token exchange (RFC 8693) and vendor equivalents such as the Microsoft identity platform's on-behalf-of (OBO) flow let each hop swap its token for one scoped to the next call. A typical escalation:
- A middle tier receives a user token for its own audience.
- It calls the token endpoint with that token as the subject (RFC 8693
subject_token, or the OBOassertion) and ascopeoraudienceparameter for the downstream API. - The issuer applies whatever policy it has. RFC 8693 says the meaning of
scopeis service specific and that a token is issued only if the request "meets all policy and other criteria of the authorization server". The RFC does not define that policy. - If the policy allows widening, the new token is wider. Keycloak's documentation for its standard token exchange, which became officially supported in Keycloak 26.2 in 2025, states that by default exchange "can be used to request extra scopes and audiences". Restricting exchange to downscoping takes an explicit client policy (the
downscope-assertion-grant-enforcerexecutor). - Downstream services trust the result. RFC 8693 says a consumer MUST consider only the token's top-level claims and the current actor, and that prior actors in nested
actclaims are informational only. The resource server sees a valid, broad token and nothing of the chain.
The same failure appears without a token endpoint: a broker that forwards the caller's token (the Model Context Protocol calls this "token passthrough" and forbids it), or a proxy that trusts the scopes in a token without its own authorization check. A compromised hop, including an AI agent's tool server, can then reach further than its position allows.
Why it works
The control assumption that fails is that narrowing is a property of the protocol. It is a property of each issuer's policy and each service's checks. OAuth defines how to ask for a token on someone's behalf but leaves what a caller may ask for to each deployment, so a chain is only as narrow as its most permissive hop.
Three design facts make the gap easy to miss:
- Defaults favour working over narrow. Microsoft's OBO documentation notes that a
.defaultscope requests "all the scopes that the application has permissions for", and thatpreAuthorizedApplicationscan receive scopes in an OBO flow "without the user providing consent". A middle tier with broad permissions passes them on. - The issuer cannot see intent. A request to widen looks the same as a request to narrow. Only a per-client allowlist can tell them apart.
- Exchanged tokens live in the MFA blind zone. Service-to-service exchange has no interactive sign-in, so MFA and most user-focused Conditional Access policies never see it.
CVE-2025-55241 showed how far an unchecked delegation primitive can reach. Dirk-jan Mollema found that undocumented Entra "Actor tokens", used by Microsoft services to act for users, were wrapped in an unsigned impersonation token that the legacy Azure AD Graph API accepted without validating the originating tenant, letting one tenant impersonate any user, including Global Admins, in another. He reported the tokens were valid for 24 hours, unlogged at issuance, and bypassed Conditional Access. Microsoft fixed it on July 17, 2025, three days after the report. CVE-2025-14778 is a smaller instance: Keycloak's UMA policy evaluation checked only the first requested resource.
How to detect it
- Entra sign-in logs: isolate delegation flows. In Microsoft Graph's beta
signInresource,authenticationProtocolincludes the valuesonBehalfOfandsamlOnBehalfOf. Baseline whichappIdvalues use OBO and whichresourceIdtargets they request, then alert on a new pairing. - Entra sign-in logs: partner and cross-tenant access.
crossTenantAccessType=serviceProvidermarks cross-tenant access by a service provider (partner). Microsoft's 2021 Nobelium guidance was to filter non-interactive sign-ins on that value to see partner activity in a tenant. - Okta System Log. In Okta,
app.oauth2.as.token.grant.interclient_tokenrecords a token issued through OAuth token exchange, andapp.oauth2.as.token.grant.access_tokenrecords the client, subject, grant type and token attributes. - Your own token service. RFC 8693 requires the response to include
scopewhenever the issued scope differs from the requested scope. Log requested and granted scope and audience for every exchange, as the MCP security guidance also recommends. - Impersonated writes. For Actor tokens, Mollema found reads left no logs, but writes logged the impersonated user's UPN with the Exchange display name.
Be honest about the limits: a new scope is often a new feature, many teams do not log exchange decisions, and without a per-service baseline the signal is noise. The worst case, Actor tokens, produced no read logs in the victim tenant at all.
How to stop it
- Allowlist scopes and audiences per client at the issuer. A caller should never receive more than its registered policy permits, whatever it asks for. In Keycloak, apply the downscope enforcer through Client Policies and enable the "Standard token exchange" switch only on clients that need it.
- Never pass tokens through. Services MUST NOT accept tokens not issued for them (the MCP rule), and middle tiers must reject a token whose
audis another app. Microsoft's OBO flow enforces this at the token endpoint. - Bind tokens to one resource. Use resource indicators (RFC 8707) so a token for one API is useless at another, and consider OAuth Transaction Tokens for internal call chains so the edge token never travels.
- Scope partner and admin delegation. Replace broad delegated admin with Microsoft's granular, time-bound GDAP roles, and remove relationships that are no longer in use.
- Authorize every hop, not just the first. Apply least privilege and privilege escalation review to the whole delegation chain. The guide to securing AI agent identities covers agent and tool-server hops.
- Keep exchanged tokens short-lived. RFC 8693's security considerations suggest scope plus a limited lifetime to reduce delegation abuse. That limits the window, not the breadth.
Seen in the wild
No public breach in our catalog has been attributed to a token exchange endpoint widening scope by name. The closest attributed incident is delegation that was broader than the job required:
- Nobelium abuse of reseller delegated administrative privileges (disclosed October 2021). Microsoft said Nobelium targeted more than 140 resellers and service providers and compromised as many as 14 to use their delegated admin rights into customer tenants, relationships "often neither audited for approved use nor disabled" once use ended. A fan-out breach: one partner identity, many tenants.
- CVE-2025-55241 was researcher-reported; Microsoft found no evidence of exploitation.
- Self-hosted JFrog Artifactory checked access token signatures and issuers but not scope (CVE-2026-42016), and attackers chained it with an anonymous-token leak (CVE-2026-42018) to reach admin actions; both are in CISA KEV.
- The Terraform MCP Server cross-tenant token bug (CVE-2026-16498) is the sibling failure (cross-tenant token confusion). Kerberos delegation abuse is the Active Directory version.
Sources
- No MITRE ATT&CK technique describes widening scope during token exchange or delegation. T1550.001 (Application Access Token) covers using stolen tokens for lateral movement, not a hop that issues itself a broader one, so
attack_mitreis left empty rather than forced. - RFC 8693: OAuth 2.0 Token Exchange
- Microsoft identity platform: OAuth 2.0 on-behalf-of flow
- Microsoft Graph: signIn resource (authenticationProtocol, crossTenantAccessType)
- Keycloak: configuring and using token exchange and Standard Token Exchange officially supported in Keycloak 26.2
- Okta: System Log event types
- Model Context Protocol: security best practices (token passthrough, scope minimization)
- Dirk-jan Mollema: obtaining Global Admin in every Entra ID tenant with Actor tokens
- Microsoft Security: NOBELIUM targeting delegated administrative privileges
- Microsoft Partner Center: GDAP introduction
Related identity CVEs and breaches
Related on Start with Identity
- CVEIvanti Connect Secure root escalation, the last link in the UTA0576 chain
The privilege escalation UTA0576 chained with CVE-2026-104935 to reach root on fully patched Ivanti Connect Secure VPNs, then mine Active Directory. Patched Oct
- CVEOkta Verify for Windows local privilege escalation
Okta Verify on Windows could be turned into a local privilege escalation. The MFA app on the endpoint is part of the identity plane. Pair with Okta's 2024 FastP
- CVEVault root privilege escalation via policy-name normalization
Vault normalized policy names in a way that let a lower-privilege token become root. CVSS 7.2. Part of the August 2025 VaultFault set.
- VendorAserto
strong
- VendorAuthZed
top_tier
- Comparisonauthzed-vs-openfga
Both are Apache 2.0 Zanzibar-style ReBAC engines. SpiceDB (AuthZed) has token-based point-in-time consistency and capacity-priced managed tiers; OpenFGA is a CN