Delegation chain explorer
An orchestrator delegates to a sub-agent with token exchange
Alex asks an orchestrator agent for a report. The orchestrator holds a token for the documents API in Alex's name and hands part of the work to a research sub-agent. Each hop exchanges the token it holds for a narrower one with an act claim, so the API can see the whole chain of who acted for whom, and no hop can do more than the one before it.
AttackToken passthrough
The orchestrator hands Alex's original token to the sub-agent and the sub-agent presents it as is. No exchange, no act claim, full docs:write scope: the API sees Alex, cannot tell which agent is calling, and a sub-agent that goes wrong can write and delete in Alex's name.
- Defeats No token passthrough to upstream APIsMCP serverListed servers under MCP Authorization 2026-07-28: 0 supported, 1 partial, 0 unsupported, 33 unknown, 5 not applicable.
The chain, step by step
Step 1: Alex to Orchestrator agent
The orchestrator already holds an access token for the documents API that Alex obtained through the usual authorization code flow.
1.1. Delegation vs. Impersonation SemanticsOAuth 2.0 Token Exchange rfc
Alex's access token held by the orchestratortyp at+jwt · alg ES256 · kid docs-2026
- iss
- https://auth.docs.example
- sub
- alex
- aud
- https://api.docs.example
- client_id
- orchestrator
- scope
- docs:read docs:write
- exp
- 1790000000
- iat
- 1789996400
- jti
- a1
Unchanged since the previous token in this chain.
Step 2: Orchestrator agent to auth.docs.exampleremoved by the toggle
Delegation, not impersonation: the orchestrator identifies itself with an actor token and asks for less than it holds.
2.1. RequestOAuth 2.0 Token Exchange rfc
Step 3: auth.docs.example to Orchestrator agentremoved by the toggle
4.1. act (Actor) ClaimOAuth 2.0 Token Exchange rfc
Step 4: Orchestrator agent to Research sub-agentreplaces "hand-over"
1.1. Delegation vs. Impersonation SemanticsOAuth 2.0 Token Exchange rfc
Alex's token, forwardedtyp at+jwt · alg ES256 · kid docs-2026
- iss
- https://auth.docs.example
- sub
- alex
- aud
- https://api.docs.example
- client_id
- orchestrator
- scope
- docs:read docs:write
- exp
- 1790000000
- iat
- 1789996400
- jti
- a1
Unchanged since the previous token in this chain.
Step 5: Research sub-agent to auth.docs.exampleremoved by the toggle
2.1. RequestOAuth 2.0 Token Exchange rfc
Step 6: auth.docs.example to itselfremoved by the toggle
The chain can only grow by parties the previous token authorised, and never wider.
4.4. may_act (Authorized Actor) ClaimOAuth 2.0 Token Exchange rfc
Step 7: auth.docs.example to Research sub-agentremoved by the toggle
4.1. act (Actor) ClaimOAuth 2.0 Token Exchange rfc
Step 8: Research sub-agent to Documents APIreplaces "api-call"
Nothing in the token says a sub-agent is calling. The API's audit trail names Alex and the orchestrator's client id, and the scope allows writes the task never needed.
1.1. Delegation vs. Impersonation SemanticsOAuth 2.0 Token Exchange rfc
Alex's token as presented by the sub-agenttyp at+jwt · alg ES256 · kid docs-2026
- iss
- https://auth.docs.example
- sub
- alex
- aud
- https://api.docs.example
- client_id
- orchestrator
- scope
- docs:read docs:write
- exp
- 1790000000
- iat
- 1789996400
- jti
- a1
Unchanged since the previous token in this chain.
Step 9: Documents API to itself
The audit record says the sub-agent read documents for Alex by way of the orchestrator, and the API can refuse actors it does not expect.
4.1. act (Actor) ClaimOAuth 2.0 Token Exchange rfc
Step 10: Documents API to Research sub-agent
4. Validating JWT Access TokensJSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens rfc
Requirements this chain exercises
- No token passthrough to upstream APIsMCP server
- Audience validationMCP server