The Task Travels. The Token Should Not.
Following one development task across a personal assistant, coding agent, chat MCP, and production deployment without forwarding the original token.
A detour from The Agent Authorization Standard We Already Had that follows the whole chain end to end, because one hop never got anyone paged.
Forwarding the token you already have is seductive. It is also how authority intended for one service quietly wanders into three others, how every action gets attributed to the user, and how an audit trail becomes a work of fiction.
So let's follow one task through the whole chain. Nadia remains the subject whose authority is being exercised. The current actor changes at each hop. The audience changes for every receiving service. The authorization server evaluates each exchange and creates a token for that boundary.1
The examples use JWT claims because they make the delegation chain visible. The agents are not opening Nadia's token, changing the audience, adding themselves as actors, and signing it again. The authorization server does that work after validating identity and policy.
Follow One Development Task Through the Chain
Let's take a look at what might happen if we follow a whole dev task down a chain. It starts with Nadia being issued a token intended for her personal assistant:
Note: These examples show the claims in tokens minted by the authorization server at each boundary. The agents are not editing or re-signing Nadia's original token.
{
"iss": "https://auth.example.com",
"sub": "nadia",
"aud": "personal-assistant",
"scope": "development.coordinate",
"may_act": {
"sub": "personal-assistant"
}
}
The personal assistant first needs the context from Slack. It authenticates as itself and exchanges Nadia's authority for a token intended only for the chat MCP:
{
"iss": "https://auth.example.com",
"sub": "nadia",
"aud": "chat-mcp",
"scope": "messages.read",
"act": {
"sub": "personal-assistant"
}
}
The personal assistant reads the development request, decides that code needs to change, and exchanges Nadia's original authority for a separate token intended for the coding agent:
{
"iss": "https://auth.example.com",
"sub": "nadia",
"aud": "coding-agent",
"scope": "code.change",
"act": {
"sub": "personal-assistant"
},
"may_act": {
"sub": "coding-agent"
}
}
Where A2A Fits
In this example, the personal assistant could invoke the coding agent over A2A. The coding agent's Agent Card advertises its authentication requirements, but A2A does not replace the authorization model described above. With an HTTP-based A2A binding, the personal assistant still sends a token intended specifically for the coding agent in the Authorization header. When the coding agent later calls the deployment MCP, it exchanges that authority for a new token whose audience is the deployment MCP. A2A carries the task; OAuth carries the bounded authority.2
The chat-MCP token and coding-agent token are siblings. One is not forwarded into the other. The same user authority has been exchanged into two separate tokens, each with its own audience and capability (delegation).
The coding agent then does its thing and produces the production code and, because staging is for cowards, needs to communicate with the Prod deployment MCP. It does not forward the token it received from the personal assistant. It authenticates as the coding agent and exchanges the incoming authority for a new token intended only for deployment:
{
"iss": "https://auth.example.com",
"sub": "nadia",
"aud": "deployment-mcp",
"scope": "deploy.production",
"act": {
"sub": "coding-agent", // the current actor, not a ceremonial title
"act": {
"sub": "personal-assistant" // useful for audit, less useful as a scapegoat
}
}
}
The outermost act entry is now the current actor, and the nested entry is the previous actor. Continue nesting and the token carries a delegation history. It is bureaucracy, but at least it is useful bureaucracy.
There is a counter-intuitive rule here. RFC 8693 says authorization decisions should consider the token's top-level claims and the current outermost actor. Previous actors are informational only. Log the entire chain, but do not quietly turn the third agent in the history into an undocumented policy input.
The subject stays Nadia. The current actor changes. The audience changes. The scope changes to the minimum capability required at each boundary. This is what we wanted from the start: the development task travels, but the original access token does not.
The Audit Record Finally Stops Lying
Without explicit delegation, the production deployment record might look like this:
principal=nadia
action=deploy_release
Technically true, in the sense that Nadia's authority was used. Operationally it's a flat out lie, because Nadia did not perform the deployment.
With the delegated token, the deployment MCP can record:
principal=nadia
current_actor=coding-agent
previous_actor=personal-assistant
audience=deployment-mcp
scope=deploy.production
token_id=at-123
action=deploy_release
The policy can also distinguish between Nadia deploying directly and the coding agent deploying for Nadia:
Allow when:
iss = trusted authorization server
sub = Nadia
act.sub = Coding Agent
aud = Deployment MCP
scope = deploy.production
Deny:
scope = deployment.admin
This is where agent identity becomes useful rather than decorative. The deployment system can apply different limits to Nadia's personal assistant and coding agent, block one actor without pretending Nadia herself is compromised, and reconstruct the complete path during the inevitable production incident.
Delegation separates ownership of authority from responsibility for exercising it. That sentence is a bit dry, but it is the entire point.
This Is Not a Complete Agent Security Architecture
RFC 8693 does not define how unrelated agent domains establish federation. It does not define a universal agent identifier, a maximum delegation depth, an approval experience, agent reputation, task-specific permissions, or a global button that revokes one agent's authority everywhere immediately.
It gives us delegation semantics. We still have to design the trust model and policy. Which is something I fear many people are abstracting away too willingly these days.
In practice that means setting a maximum actor-chain depth, using short-lived and audience-specific access tokens, validating issuer, audience, expiry and scope, authenticating the actor independently during exchange, and verifying what the chosen authorization server actually emits.
Bearer tokens still have an obvious weakness: whoever holds one can usually use it. If token theft is a material risk, sender-constrained mechanisms such as Demonstrating Proof of Possession (DPoP)3 or mutual Transport Layer Security (mTLS)4 can bind the token to a key held by the intended presenter.
What I Would Implement First
If I were turning this example into a real system, I would start with four controls: one token per audience, short token lifetimes, independently authenticated actors during exchange, and audit records that store the full delegation chain. Then I would add local limits for chain depth and sender-constrained tokens where theft presents a material risk.
You do not need every possible agent-security mechanism on day one. You do need to stop forwarding broad user tokens and pretending that the user performed every downstream action.
But compare this with where we started. The chat MCP required Nadia's personal assistant to obtain a token. By the time the code reaches production, the deployment MCP can answer five useful questions:
Who owns the authority? Nadia
Who is exercising it? Coding Agent
Who acted previously? Personal Assistant
Where can it be used? Deployment MCP
What can it do? deploy.production
AI agents may be new to the party, but delegation is not a new security problem. RFC 8693 already gives us a vocabulary for the subject, the actor, the permitted delegate, and the target. RFC 9728 gives an unfamiliar client a standard way to begin the authorization conversation. A2A carries the task from personal assistant to coding agent, while MCP exposes the chat and deployment capabilities behind explicit authorization boundaries.
The challenge is not inventing another token format. It is applying the authorization machinery we already have with discipline.
The conversations around agents feel increasingly familiar: boundaries, domains, responsibilities, and accountability. Apparently the future of AI still requires the same old arguments about who is allowed to do what. The technology changes quickly. The meetings remain remarkably stable.
The safest agent systems may not be built on novel authorization technology, but on old authorization technology used precisely.