Identity and Authorization Chaining Across Domains
The general mechanism for carrying identity across a trust boundary. ID-JAG is a profile of it.
Flows / Delegation chains
Carry who-is-this-for across an organizational boundary, with each side keeping control of its own tokens.
Token exchange works inside one trust domain, where a single authorization server can mint a token for any hop. Agent workflows do not stay inside one domain. An agent in company A calls a service run by company B. Company B will not accept company A’s tokens, and should not.
Identity chaining combines two existing pieces to cross the boundary. In its home domain, the agent uses token exchange to obtain a short-lived JWT authorization grant addressed to the other domain’s authorization server. It then presents that grant to the other side using the JWT bearer grant, and receives an access token that the second domain issued under its own policy. Each domain validates only what it issued or explicitly agreed to trust, and the pattern repeats for every further boundary.
The specification is through IETF approval and waiting in the RFC Editor’s queue.
9 steps between 4 parties. Each step shows the message and who holds which credential afterward. Use ←→ or select any arrow.
Drag to see every party and step. Tap a step to jump to its explanation.
The agent holds a token issued in domain A, for a user or for itself. It needs to call an API protected by domain B’s authorization server.
Who holds what after this step
Parties not listed hold none of this flow’s credentials at this point.
A token exchange request (RFC 8693) whose target is the other domain’s authorization server.
POST /token HTTP/1.1
Host: as.a.example
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&subject_token=<token from domain A>
&subject_token_type=urn:ietf:params:oauth:token-type:access_token
&requested_token_type=urn:ietf:params:oauth:token-type:jwt
&audience=https://as.b.example
&scope=orders.readWho holds what after this step
Parties not listed hold none of this flow’s credentials at this point.
The home authorization server controls outbound trust: which clients may obtain grants for which external domains, and which claims about the user are released.
Who holds what after this step
Parties not listed hold none of this flow’s credentials at this point.
Signed by domain A. Its audience is domain B’s authorization server and nothing else. It is not an access token and no API should accept it.
{
"iss": "https://as.a.example",
"sub": "alice@a.example",
"aud": "https://as.b.example",
"client_id": "research-agent",
"scope": "orders.read",
"jti": "c3f1…",
"exp": 1794268920
}Who holds what after this step
Parties not listed hold none of this flow’s credentials at this point.
An RFC 7523 assertion grant at domain B’s token endpoint. The agent also authenticates as a client known to domain B.
POST /token HTTP/1.1
Host: as.b.example
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
&assertion=<JWT authorization grant>
&resource=https://api.b.exampleWho holds what after this step
Parties not listed hold none of this flow’s credentials at this point.
Domain B verifies the signature against keys it has agreed to trust for domain A, checks it is the audience, and maps the incoming subject and claims to its own. It is free to grant less than was asked.
Who holds what after this step
Parties not listed hold none of this flow’s credentials at this point.
An ordinary access token, issued and revocable by domain B, with domain B’s idea of who the subject is.
Who holds what after this step
Parties not listed hold none of this flow’s credentials at this point.
The API validates a token from its own authorization server. It never sees anything issued by domain A.
Who holds what after this step
Parties not listed hold none of this flow’s credentials at this point.
Either domain can end the arrangement independently: A by refusing to issue grants, B by refusing to honor them.
Who holds what after this step
Parties not listed hold none of this flow’s credentials at this point.
ID-JAG is a profile of this pattern for one common case: the first authorization server is an enterprise identity provider and the input is the user’s single sign-on assertion. The WIMSE working group’s agent architecture document recommends identity chaining or ID-JAG whenever an agent crosses a trust domain.
See the full tracker for status and links.
The general mechanism for carrying identity across a trust boundary. ID-JAG is a profile of it.
The primitive under on-behalf-of flows, ID-JAG, identity chaining and transaction tokens.
Secretless client authentication, and the second leg of ID-JAG and identity chaining.
Any agent using private_key_jwt or JWT bearer grants should follow it. Published this month.
Lets a company’s identity provider decide which agent may reach which application for which employee.
The closest thing to an IETF reference architecture for agent authentication and authorization. Its opening position: agents are workloads.
The company identity provider decides which agents may reach which apps for which employees. No per-app consent screens.
Trade the token you were given for a new one that names both the user and the service now acting for them.
Inside your own infrastructure, replace the access token with a short-lived token that pins down one transaction and travels the whole call chain.
Your agent uses an identity established by its runtime to obtain short-lived access from a system that trusts that identity.