Standardization around token exchange is moving faster than at any point in the past decade. From RFC 8693, OAuth 2.0 Token Exchange, to the Internet Engineering Task Force (IETF) drafts for OAuth Identity and Authorization Chaining Across Domains, JSON Web Token (JWT) profile Identity Assertion JWT Authorization Grant (ID-JAG) for Cross-App Access (XAA), and OAuth Actor Chain: Protocol and Interoperability, the identity industry is pouring enormous energy into moving identity assertions silently across trust boundaries. That momentum is not the problem.
The problem is that the industry is rushing to standardize protocol mechanics for cross-domain token exchange without stepping back to ask whom those mechanics actually serve. Cross-domain token exchange is not a security control, and it is not helping anyone solve the governance problem they think they are solving. It exists to make cross-boundary calls easier for application code and invisible to the user, while leaving the hard identity governance work untouched and handing a much more dangerous failure mode to the security operations center (SOC) analyst at 2:00 AM and the auditor six months later.
I am all for standardization, and I care deeply about control, observability, auditability, and traceability. In The industry does not have an agent identity propagation standard yet, I mapped the mechanics that are still missing when user context travels across multi-hop agent chains. In Your API gateway is not an identity provider, and promoting it to one is a liability, I argued that letting an API gateway mint tokens turns middleware into an ungoverned authorization server.
This article takes the next logical step in that argument, and it is the one that makes design reviews uncomfortable. Even when you take the gateway out of the token-minting business and let two real identity providers (IdPs) exchange tokens directly through a standards-track flow, bridging separate security domains with silent token exchange is still the most dangerous patch you can apply to a fragmented identity estate. Inside a single authorization server, where an on-behalf-of (OBO) exchange stays under one policy engine, one subject namespace, and one revocation switch, token exchange is a sound pattern. Across identity providers, it trades a visible security boundary for an invisible compromise path.
Running two identity providers is already an accepted risk
Step back from the protocol diagrams for a moment and name the enterprise state honestly. Almost every large organization runs at least two IdPs today, and even with executive backing and a funded consolidation roadmap, most will continue to run at least two IdPs for the foreseeable future. Acquisitions, regional regulatory splits, legacy workforce directories alongside cloud identity platforms, and vendor-embedded authorization servers do not disappear overnight. Artificial intelligence (AI) adoption has to live in that brownfield reality and operate securely inside it.
Calling that state inevitable does not make it safe. Running multiple IdPs is an accepted risk, and there is no cleaner word for it. Every additional IdP introduces another policy engine, another administrative surface, another signing-key lifecycle, another audit schema, and another set of human and non-human lifecycle rules. Where two policy surfaces meet, a seam forms between them.
Adversaries do not attack the strongest control inside a single directory when a seam between two directories is available. They find and weaponize policy gaps across boundaries faster than defenders can inventory them. The 2026 Microsoft Digital Defense Report puts numbers to that reality across more than 165 trillion daily security signals and 31 million daily identity risk detections: 78% of observed attack techniques against critical infrastructure used cloud identity abuse, and 52.2% of valid account intrusions involved follow-on credential theft because one compromised identity fuels the compromise of many more identities (2026 Microsoft Digital Defense Report full PDF).
Notice how the 2026 Microsoft Digital Defense Report frames the shift in its opening statement: in an era of interconnected risk, attackers increasingly exploit the trusted identities, systems, relationships, and services that organizations rely on most. The report also notes that 88% of enterprises are already experimenting with AI agents, with 82% of leaders planning broader rollouts within 12-18 months and industry projections pointing to 1.3 billion AI agents in production by 2028. When you place fast-moving AI agents on top of a multi-IdP estate, every cross-domain trust bridge becomes a machine-speed lateral movement path.
Observations from the Microsoft Detection and Response Team (DART) in the same 2026 Microsoft Digital Defense Report make the operational dynamic explicit. The core adversary playbooks have not changed: identity compromise, credential reuse, privilege escalation, and access misuse remain the foundation of intrusions, with 89-95% of email phishing attachments leading to a credential theft effort. What changed in 2026 is the scale of access, the speed of execution (with exposed cloud workloads attacked in an average of 5.3 hours), the surge in non-human identities, and the automation and orchestration of attacks. An architecture that assumes two IdPs can safely trade assertions in the background because neither has been breached yet is ignoring how modern intrusions actually unfold.
The National Institute of Standards and Technology (NIST) reaches the same structural conclusion in NIST Special Publication (SP) 800-207, Zero Trust Architecture. Zero Trust requires that access to individual enterprise resources be granted on a per-session basis, evaluated dynamically by a policy engine and enforced by a policy enforcement point, and that authentication or authorization to one resource never automatically grant access to another resource. When your architecture splits that decision across two or three independent policy engines that do not share runtime state, risk signals, or entitlement graphs, the seam between them is the exact place where implicit trust creeps back in.
That seam is not theoretical. In a single-IdP design, the policy engine sees the user's sign-in risk, the device posture, the client application's registration status, and the target resource's sensitivity in one evaluation pass. In a dual-IdP design bridged by token exchange, the first policy engine evaluates the user without knowing the true state of the downstream resource, and the second policy engine evaluates the downstream resource without direct visibility into the user's live session or the upstream device.
Microsoft's Cybersecurity and Infrastructure Security Agency (CISA) Zero Trust Maturity Model guidance for the identity pillar and the enterprise-wide identity management guidance for Office of Management and Budget (OMB) Memo M-22-09 both point in one direction: consolidate identity providers and identity stores so fewer systems can assert who a principal is. While you are living with two IdPs, the architectural goal is to contain the blast radius of each domain, not to wire them together so tightly that a compromise in one becomes an automatic ticket into the other.
A trust relationship across identity providers is a compromise relationship
Why is cross-domain token exchange more toxic than a casual reading of the specifications suggests? Because in federated identity, every trust relationship you configure is also a compromise relationship.
A JWT exchange between IDP 1 and IDP 2 does not happen by magic. IDP 2 will not accept tokens from IDP 1 presented by an arbitrary client unless an administrator explicitly configures a trust relationship between those two issuers. In the IETF's OAuth Identity and Authorization Chaining Across Domains draft (draft-ietf-oauth-identity-chaining-17, Section 2.1), the client in Trust Domain A exchanges its inbound token at Authorization Server A for a JWT authorization grant, and then presents that grant via RFC 7523, JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants, to Authorization Server B. For step 5 of that flow to succeed, Authorization Server B must trust the public signing keys in Authorization Server A's JSON Web Key Set (JWKS) and must trust Authorization Server A's authority to assert subjects into Domain B.
In a real enterprise, you rarely configure that trust once. You have multiple API gateways, regional instances, business-unit tenants, and SaaS resource authorization servers protecting downstream tools such as a Model Context Protocol (MCP) server. Every time a team needs an agent or service in Domain 1 to reach an MCP server in Domain 2 without prompting the user, someone adds another issuer-trust entry, another audience allowlist, and another claim-mapping rule. Before long, IDP 2 is not merely trusting one carefully governed enterprise directory; it is trusting a mesh of upstream issuers and intermediary gateways, any one of which can mint an assertion that unlocks Domain 2.
flowchart LR
Alice["Compromised claim<br/>or rule in IDP 1"]
IDP1["IDP 1<br/>Issues ID-JAG<br/>sub: Bob"]
GW["API Gateway<br/>Routes and bridges<br/>trust domains"]
IDP2["IDP 2<br/>Validates IDP 1 key<br/>Resolves local Bob"]
MCPZ["MCP Server Z<br/>Executes as Bob<br/>in Domain 2"]
Alice -->|"1. Forges or<br/>hijacks context"| IDP1
IDP1 -->|"2. Signs grant<br/>aud: IDP 2"| GW
GW -->|"3. Presents<br/>RFC 7523 grant"| IDP2
IDP2 -->|"4. Mints local<br/>access token"| MCPZ
linkStyle 1 stroke:#d62728,stroke-width:3px
linkStyle 2 stroke:#d62728,stroke-width:3px
linkStyle 3 stroke:#d62728,stroke-width:3px
Look at what that diagram actually represents when something goes wrong. IDP 2 has no direct proof that Bob authenticated, what authenticator he used, what device he is on, or whether his session in IDP 1 was hijacked by an infostealer five minutes ago. IDP 2 only knows that a cryptographic signature matched a public key published at IDP 1's jwks_uri, and that the string inside the sub or sub_id claim maps to a local user named Bob.
That means cross-domain token exchange directly invalidates the Verify explicitly principle of Zero Trust. Microsoft's Zero Trust model states the first principle without ambiguity: always authenticate and authorize based on all available data points, including user identity, location, device health, service or workload, data classification, and anomalies. When IDP 2 mints an access token from a cross-domain exchange, it is not explicitly verifying the user (Bob), and in a brokered or chained exchange it is not explicitly verifying the upstream client context either. It is verifying a signature from a foreign authority and blindly trusting that the foreign authority verified everything else. Validating a foreign issuer's cryptographic key is not explicit verification of the principal. It is delegated faith.
Recall what RFC 7519 Section 4.1.2 says about the sub claim: its value is only guaranteed to be unique locally within the scope of the issuer. To bridge two different subject namespaces, draft-ietf-oauth-identity-assertion-authz-grant-04 Section 3.1 and Section 3.2 allow the ID-JAG to carry both an OpenID Connect (OIDC) sub claim and an optional sub_id claim formatted as a Security Assertion Markup Language (SAML) NameID object containing issuer, nameid, nameid_format, and sp_name_qualifier. That translation mechanism is convenient for interoperability, and lethal when an upstream mapping is subverted.
If IDP 1 is compromised, or if an over-permissive claim-mapping rule in IDP 1 allows Alice or a compromised sub-agent to obtain a grant whose sub or sub_id resolves to Bob, IDP 2 will validate the signature, resolve the local Bob account, and mint a fresh Domain 2 access token for Bob. From that instant inward, every resource server in Domain 2 sees a native, cryptographically pristine token issued by IDP 2 that satisfies RFC 9068, JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens.
Even draft-ietf-oauth-identity-chaining-17 Section 5.3 explicitly warns about this exact vector: an attacker can make a lateral move by taking a stolen token from Trust Domain A, using token exchange to obtain an authorization grant, and authenticating to Authorization Server B to access protected resources in Trust Domain B. When you automate that exchange in the back channel, lateral movement across security domains no longer requires an exploit against IDP 2. It only requires calling the token endpoint as designed.
This is not a hypothetical edge case. NIST SP 800-63C-4, Digital Identity Guidelines: Federation and Assertions, states this exact failure mode in two separate places:
- In Section 3.3.3 on Proxied Federation, NIST specifies that the Federation Assurance Level (FAL) of a connection through a proxy or broker to a downstream relying party (RP) is never higher than the lowest FAL along the entire path. A high-assurance token minted by
IDP 2at the end of a chain cannot launder a weak or compromised assertion fromIDP 1. - In Section 2.3 on Federation Assurance Level 3 (FAL3), NIST notes that protecting against the possibility of a compromised IdP requires additional authentication by the subscriber at the relying party, where the relying party verifies that the subscriber controls a bound authenticator in addition to the assertion.
Read that second requirement again. The only way NIST's highest federation assurance level protects a downstream domain against a compromised upstream IdP is by requiring the user to prove possession of an authenticator at the boundary. Silent cross-domain token exchange is designed specifically to eliminate that boundary check. When you remove the check at the border, you bind the survival of IDP 2 to the configuration hygiene and key custody of IDP 1.
The steelman case for cross-domain token exchange deserves a direct answer
If you challenge token exchange in an architecture review, proponents of the emerging standards will not fold easily. They will raise three strong counter-arguments grounded in the specifications themselves. If your position is going to survive contact with a standards-literate room, you have to state their best arguments fairly and show why the underlying architectural flaw remains.
Counter-argument 1: "Border exchanges are not blind; ID-JAG and RFC 8707 support fine-grained scopes and resources"
It is tempting to argue that a cross-domain token exchange is always a broad, coarse request: "I have a token from IDP 1, give me a token in IDP 2 for whatever lives behind IDP 2." If you state it that bluntly, an architect who has read draft-ietf-oauth-identity-assertion-authz-grant-04 will immediately push back.
In Section 4.3 of the ID-JAG specification, the token exchange request to IDP 1 does not merely ask for a generic cross-domain assertion. It profiles audience to name the target Resource Authorization Server (IDP 2), uses RFC 8707, Resource Indicators for OAuth 2.0, via the resource parameter to name the specific downstream API (for example, MCP Server Z), carries scope, and can even carry structured JSON objects via RFC 9396, OAuth 2.0 Rich Authorization Requests (RAR), in authorization_details. On paper, the protocol grammar is as fine-grained as you could ask for.
Here is why that rebuttal collapses in practice. Protocol syntax for a fine-grained scope is not the same thing as an authorization server knowing what that scope means.
When the AI agent asks IDP 1 for an ID-JAG targeting IDP 2 (audience=https://idp2.example/) and MCP Server Z (resource=https://mcp-z.example/) with scope=records.export, how does IDP 1 decide whether to grant that request? MCP Server Z is registered in IDP 2, not IDP 1. IDP 1 does not own MCP Server Z's role definitions, data classification, or entitlement assignments.
You now have only two options, and both are bad:
-
IDP 1treats the border exchange as a coarse pass-through.IDP 1checks only that the agent is allowed to talk toIDP 2in general, copies the requestedresourceandscopestrings into the signed ID-JAG, and leaves the real decision toIDP 2. In that case, your border exchange is broad atIDP 1, andIDP 1is signing fine-grained claims it never actually evaluated. -
You duplicate MCP Server Z's authorization model inside
IDP 1. To make a real fine-grained decision atIDP 1, administrators must replicate Domain 2's resource identifiers, scope semantics, and user-to-role policies into Domain 1's policy engine. Even the OAuth Actor Chain specification (draft-mw-oauth-actor-chain-02, Section 2) admits the trap here: it compares OAuth scope strings as written, and explicitly notes that differently named scopes in different domains cannot be assumed to mean the same thing.
So the protocol lets you type a granular string into the HTTP POST body. Architecturally, either the source IdP rubber-stamps a permission it does not understand, or you maintain the same fine-grained policy in two separate IdPs and pray they never drift. Looking at Section 4.3.3 and Section 4.4.1 of draft-ietf-oauth-identity-assertion-authz-grant-04 side by side exposes the redundancy: Section 4.3.3 requires IDP 1 to parse and evaluate policy over resource, scope, and authorization_details, and then Section 4.4.1 requires IDP 2 to parse and evaluate policy over the exact same resource, scope, and authorization_details claims again. Calling that "fine-grained cross-domain authorization" confuses writing a policy twice with having a single source of truth.
Counter-argument 2: "Interactive prompts create consent fatigue and break autonomous agents"
The second pushback is about user experience and automation. Appendix A.1 of draft-ietf-oauth-identity-assertion-authz-grant-04 argues that traditional OAuth redirects between applications force end users through repeated interactive consent screens, encouraging shadow-IT app-to-app grants that the enterprise IdP never sees. Proponents also point out that a headless autonomous agent running a background workflow cannot complete an interactive browser sign-in when it crosses into IDP 2.
Separate the two cases that this objection conflates:
-
Fully autonomous workloads do not need user-context token exchange. As I covered in The industry does not have an agent identity propagation standard yet, when an agent acts on its own behalf without a human
subclaim, Microsoft Entra workload identity federation or direct client authentication to the target domain solves the problem cleanly. And if an autonomous agent requests access to a sensitive resource in another security domain that it does not hold standing privilege for, the right control is an asynchronous access-request or approval workflow, not a silent background token swap. - For human-delegated agents crossing security domains, friction is the control. Look at the 2026 Microsoft Digital Defense Report table of the five risk classes defining the 2026 agentic attack surface. Two of those five classes are Identity and privilege compromise (where attackers impersonate a sub-agent, reuse stolen credentials, or chain privileges across agents) and Excessive agency (where attackers coax an agent into chaining tools or actions beyond sanctioned behavior). What does Microsoft Threat Intelligence prescribe as the defensive control for excessive agency? Tool allow-listing, runtime gating, action policy, and anomaly detection.
Look also at how NIST SP 800-63C-4 Section 3.3.2 on Authorized Party and Section 2.5 on Requesting and Processing xALs structure federated decisions. While an enterprise can pre-authorize routine attribute release through an allowlist, the relying party still determines the minimum Identity Assurance Level (IAL), Authenticator Assurance Level (AAL), and FAL required for a specific action, and can require a higher assurance level for higher-impact operations. When an agent moves from summarizing a low-sensitivity chat thread in Domain 1 to invoking a state-changing MCP tool in Domain 2, the risk profile changes at the boundary.
When an AI agent acting for Bob crosses an organizational trust boundary from IDP 1 into IDP 2 to invoke that tool, an interactive confirmation, a step-up challenge via RFC 9470, OAuth 2.0 Step Up Authentication Challenge Protocol, or a single sign-on (SSO) prompt is runtime gating in action. Even draft-ietf-oauth-identity-assertion-authz-grant-04 Section 9.2 concedes that when authentication context does not meet policy requirements, the IdP returns insufficient_user_authentication and forces the client to redirect the user back to the IdP anyway. Sacrificing a few seconds of invisible friction at a security domain boundary in exchange for explicit user confirmation, fresh Conditional Access evaluation, and a clean audit event in the target IdP is a trade every security architect should gladly make.
Counter-argument 3: "OAuth Actor Chain gives the SOC cryptographic lineage across every hop"
The third pushback comes from the authors of OAuth Actor Chain: Protocol and Interoperability (draft-mw-oauth-actor-chain-02). They will agree that RFC 8693 Section 4.1 left nested act claims purely informational for access control, and argue that Actor Chain fixes that gap for the auditor and the SOC.
Actor Chain defines six assurance and disclosure profiles (declared-full, declared-subset, declared-actor-only, verified-full, verified-subset, and verified-actor-only), four new JWT claims (actp for profile, acti for workflow identifier, actc for current authorization-server-signed acceptance, and acte for the evidence envelope), and three transitions (root, extend, and preserve). In its verified profiles, every actor signs a compact JSON Web Signature (JWS) step proof and every authorization server signs an acceptance chaining the exact bytes of the previous hop, advertising capability limits up to max_depth: 10 and max_inline_bytes: 32768.
Now read what the specifications themselves admit about that machinery:
-
ID-JAG does not even process actor tokens normatively. Section 9.7 of draft-ietf-oauth-identity-assertion-authz-grant-04 states plainly that while ID-JAG requests may carry
actor_token, the specification defines no normative processing requirements for it or for whether anactclaim appears in the issued grant. -
Cross-domain chaining rewrites claims in transit. Section 2.5 of draft-ietf-oauth-identity-chaining-17 ("Claims Transcription") explicitly allows authorization servers at domain boundaries to add, remove, or change claims, including rewriting a subject identifier from
johndoe@a.examplein Domain A todoe.john@b.examplein Domain B, while stating that the representation and format of transcribed claims are not defined by the specification. - Exchange-time signatures do not prove live presentation without another layer of key binding. Section 16 and Section 24.5 of draft-mw-oauth-actor-chain-02 point out that an actor's step proof only shows which actor signed an authorization transition at exchange time; it does not prove that the entity presenting the token now controls that key unless the deployment also enforces sender-constrained tokens via RFC 9449, OAuth 2.0 Demonstrating Proof of Possession (DPoP). Worse, Section 24.6 warns that replay atomicity across an accepting authorization server requires distributed fencing and durable commit, trading token-endpoint availability for safety whenever authoritative replay state is partitioned.
- Cryptographic step proofs do not prove policy correctness or human intent. Section 24.8 of draft-mw-oauth-actor-chain-02 ("Residual Non-Claims") is admirably candid: Actor Chain does not prove application execution, payload safety, human intent, legal non-repudiation, correctness of authorization policy, absence of hidden branches, or absence of off-protocol activity.
Shipping up to 32 kilobytes of nested JWS proofs in a token header (or forcing every downstream resource server to make live RFC 7662 token introspection calls across trust domains) only proves that a sequence of workloads signed requests that authorization servers accepted. It does not tell you whether the subject mapping between IDP 1 and IDP 2 was legitimate, and it does not give you a single kill switch when it was not.
Trace Bob and the AI agent to MCP Server Z and count what you actually saved
To see how little operational complexity cross-domain token exchange actually removes, walk the exact scenario that every enterprise AI team is currently drawing on their whiteboard.
Bob signs in to IDP 1 and invokes an AI agent registered in IDP 1. During its execution plan, the agent needs to invoke MCP Server Z to read or modify enterprise records. MCP Server Z is protected by IDP 2, not IDP 1.
Instead of redirecting Bob to IDP 2 (which would complete over enterprise SSO if Bob is present, or trigger an explicit step-up / access approval check), the architecture team decides to use cross-domain token exchange via ID-JAG (draft-ietf-oauth-identity-assertion-authz-grant-04 Appendix A.4).
First, the AI agent sends a token exchange request to IDP 1 to trade Bob's identity assertion (subject_token) for an id-jag targeting IDP 2 and MCP Server Z:
POST /oauth2/token HTTP/1.1
Host: idp1.enterprise.example
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&requested_token_type=urn:ietf:params:oauth:token-type:id-jag
&audience=https://idp2.partner.example/
&resource=https://mcp-z.partner.example/
&scope=mcp.tools.execute
&subject_token=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9...
&subject_token_type=urn:ietf:params:oauth:token-type:id_token
&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
&client_assertion=eyJhbGciOiJFUzI1NiIsImtpZCI6ImFnZW50LWtleS0xIn0...
Second, IDP 1 returns a signed JWT with header "typ": "oauth-id-jag+jwt". The AI agent then takes that grant over to IDP 2's token endpoint and presents it using the RFC 7523 JWT bearer grant type, authenticating itself as a client of IDP 2:
POST /oauth2/token HTTP/1.1
Host: idp2.partner.example
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
&assertion=eyJhbGciOiJFUzI1NiIsInR5cCI6Im9hdXRoLWlkLWphZytqd3QifQ...
&scope=mcp.tools.execute
&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
&client_assertion=eyJhbGciOiJFUzI1NiIsImtpZCI6ImFnZW50LWtleS0yIn0...
Look closely at what had to be pre-configured in both identity providers for those two HTTP requests to succeed. You do not have to guess; Appendix A.4.1 of draft-ietf-oauth-identity-assertion-authz-grant-04 ("AI Agent using External Tools: Preconditions") lists the requirements explicitly, covering client registration (static or via an OAuth Client ID Metadata Document (CIMD)), joiner-mover-leaver (JML) account synchronization or just-in-time (JIT) subject provisioning, JWKS key trust, and per-domain scope policies.
+-------------------------------------------------------------------------+
| THE CROSS-DOMAIN GOVERNANCE LEDGER |
+------------------------------------+------------------------------------+
| DOMAIN 1 (IDP 1: Source) | DOMAIN 2 (IDP 2 + MCP Server Z) |
+------------------------------------+------------------------------------+
| 1. Register AI Agent as a trusted | 1. Register the SAME AI Agent as a |
| OAuth 2.0 client (client_id, | trusted OAuth 2.0 client and |
| keys, or CIMD allowlist). | validate its client credentials.|
| | |
| 2. Provision Bob and maintain his | 2. Provision Bob (or JIT-map him) |
| JML lifecycle in IDP 1. | and maintain his JML lifecycle |
| | and local sub / sub_id mapping. |
| | |
| 3. Configure federation trust and | 3. Configure issuer trust and JWKS |
| audience mapping for IDP 2. | validation for IDP 1 grants. |
| | |
| 4. Author policy allowing Agent | 4. Author local policy allowing |
| to request ID-JAGs on behalf | both Agent AND Bob to invoke |
| of Bob for MCP Server Z scopes. | MCP Server Z with those scopes. |
+------------------------------------+------------------------------------+
| PLUS: Every API Gateway in the path enforcing routing, audience |
| rewrites, or intermediate token exchanges of its own. |
+-------------------------------------------------------------------------+
Pause and read that ledger line by line, because this is where the marketing story around token exchange falls apart.
First, you did not save the developer from registering the AI agent in both identity providers, even though IDP 2 still blindly trusts IDP 1 about how the agent and Bob met. Section 4.4.1 of draft-ietf-oauth-identity-assertion-authz-grant-04 requires IDP 2 to authenticate the client making the RFC 7523 request and check that its authenticated identity matches the client_id claim inside the ID-JAG minted by IDP 1. Whether you use static client registration or CIMD (which, as I wrote in Dynamic client registration and CIMD are not a trust framework, still requires governance and allowlisting), both IDP 1 and IDP 2 must recognize, authenticate, and govern the AI agent as a confidential client. Yet even with that dual registration, IDP 2 never explicitly verifies Bob, never sees the upstream client-to-user authorization ceremony, and in a gateway-brokered RFC 8693 exchange does not even see the original client at all; it takes a token issued by a foreign authority on blind trust and treats that foreign assertion as a substitute for Zero Trust explicit verification.
Catch the irony in that requirement. Half the pitch for cross-domain token exchange in developer conversations is that application teams only have to integrate with their home IdP and can let token exchange handle the rest. Yet in step 2 of the exchange, the AI agent makes a direct HTTP POST to IDP 2's token endpoint and authenticates itself as a registered client of IDP 2. If the developer already had to register the AI agent in both IDP 1 and IDP 2 and manage client credentials or federated key material in both places, the "single integration" story was an illusion from the start.
Second, you did not save the organization from maintaining Bob's identity lifecycle in both identity providers. Section 2.2 of draft-ietf-oauth-identity-assertion-authz-grant-04 defines Subject Resolution as the process by which IDP 2 determines which local subject represents the end user identified in the ID-JAG, using iss, sub, tenant, or a SAML NameID carried in sub_id (RFC 9493, Subject Identifiers for Security Event Tokens). As NIST SP 800-63C-4 Section 3.4 warns, different IdPs manage subject identifiers independently. Bob must exist as a resolved subject in IDP 2, and Bob must hold a role or entitlement in MCP Server Z. If your JML process deprovisions Bob in IDP 1 or changes his department, IDP 2's local representation of Bob and his standing entitlements in MCP Server Z still have to be updated or revoked. Relying on JIT provisioning at IDP 2 does not fix leaver deprovisioning; it only creates orphan accounts faster.
Third, you multiplied the number of places where authorization policy must be kept in sync. IDP 1 must know that this AI agent is permitted to request a cross-domain grant for IDP 2 and MCP Server Z on Bob's behalf. IDP 2 must know that IDP 1 is permitted to assert Bob, that this AI agent is permitted to redeem the assertion, and that both the AI agent and Bob are authorized to invoke MCP Server Z. And if an API gateway sits between the domains, its routing and validation policies form a third enforcement plane.
| Governance requirement | Interactive SSO or explicit boundary check | Cross-domain token exchange (RFC 8693 / ID-JAG / Chaining) |
|---|---|---|
Register and authenticate AI agent in IDP 1
|
Required | Required (ID-JAG Appendix A.4.1) |
Register and authenticate AI agent in IDP 2
|
Required only in the domain where the client requests tokens | Required in both IDP 1 and IDP 2 (ID-JAG Section 4.4.1) |
Synchronize Bob's JML lifecycle and entitlements in IDP 2
|
Required | Required (ID-JAG Section 2.2) |
| Maintain cross-IdP signing-key and token-exchange trust | SSO federation at the front door only | Full back-channel grant minting trust across domains (Identity Chaining Section 2.1) |
| Runtime human confirmation or step-up gate at domain boundary | Enforced at boundary crossing | Bypassed by design unless insufficient_user_authentication triggers (ID-JAG Section 9.2) |
| Number of policy planes deciding a single tool call | 1 at a time (explicit boundary handoff) | 3 or more (IDP 1 + Gateway + IDP 2 + Resource Server) |
Ask the uncomfortable question that table forces into the open. What did you actually achieve?
You did not eliminate dual client registration. You did not eliminate dual JML synchronization for Bob. You did not eliminate resource-level entitlement management in IDP 2. You saved one interactive boundary prompt (which, for a human user with an active enterprise session, would have completed over SSO or triggered a visible consent/step-up check in seconds), and in return you built a three-plane policy chain that turns any misconfiguration in IDP 1 into silent, valid execution in IDP 2.
Token exchange was built for the developer at 2:00 PM, not the SOC analyst at 2:00 AM
When an architecture optimizes exclusively for developer ergonomics at 2:00 PM, someone else pays the carrying cost. In cross-domain token exchange, that bill lands on two desks: the SOC analyst at 2:00 AM and the compliance auditor.
Put yourself in the chair of the SOC analyst paged at 2:00 AM because an anomaly detection rule fired on MCP Server Z in Domain 2. A sensitive dataset is being exported by an access token issued by IDP 2.
The analyst pulls the IDP 2 token issuance log and the token claims presented to MCP Server Z:
{
"iss": "https://idp2.partner.example/",
"sub": "usr_99481_bob_local",
"aud": "https://mcp-z.partner.example/",
"client_id": "https://ai-agent-app.example/",
"scope": "mcp.tools.execute",
"iat": 1792029600,
"exp": 1792033200
}
What does the analyst know from IDP 2? Only that IDP 2 issued a valid access token to https://ai-agent-app.example/ for local subject usr_99481_bob_local because the client presented an oauth-id-jag+jwt signed by IDP 1.
Now the analyst has to answer four questions before isolating the incident:
-
Which upstream identity in
IDP 1was transcribed intousr_99481_bob_local? Because draft-ietf-oauth-identity-chaining-17 Section 2.5 allows claims transcription (johndoe@a.examplemapped todoe.john@b.example) or SAMLsub_idtranslation (draft-ietf-oauth-identity-assertion-authz-grant-04 Section 3.2), the identifier inIDP 2's log does not match thesubinIDP 1's log. -
Which upstream actor or sub-agent triggered the exchange in
IDP 1? Because ID-JAG (Section 9.7) does not normatively require or processactor_tokenoract, the upstream delegation chain inside Domain 1 may not appear in theIDP 2token at all. Even if the deployment uses OAuth Actor Chain in averified-subsetorverified-actor-onlydisclosure profile (Section 15), intermediate actors are intentionally omitted from the downstream token and visible only inside the upstream authorization server's evidence store. - Did a gateway sit in the middle and translate the token? If an API gateway performed step 2.1 of the pattern I described in Your API gateway is not an identity provider, and promoting it to one is a liability, the correlation lives in application-platform gateway logs that the SOC often cannot query from the identity incident workbench.
-
Which kill switch stops the bleeding right now? If the analyst disables Bob's account in
IDP 1, the access token already minted byIDP 2remains valid until it expires (Notice that the non-normative example in Section 4.4.2 of draft-ietf-oauth-identity-assertion-authz-grant-04 shows"expires_in": 86400, a full 24 hours). Worse, Section 4.3.2 and Section 4.5 of the same specification allow a client to pass a long-livedrefresh_tokenas thesubject_tokenin a token exchange to mint new ID-JAGs without acquiring a fresh identity assertion from the user's sign-in flow, and Section 4.4.3 allows clients to re-submit an unexpired ID-JAG toIDP 2when an access token expires. Unless both IdPs enforce aggressive single-use replay caching (jti), short lifetimes, and cross-domain continuous access evaluation, cutting offIDP 1does not immediately cut offIDP 2.
The 2026 Microsoft Digital Defense Report states the defender's dilemma plainly: signal cross-correlation is one of the highest-leverage variables under a defender's control, because attack patterns remain invisible when endpoint, identity, cloud, and application telemetry are analyzed in isolation. Cross-domain token exchange fragments one logical authorization decision across two or three separate telemetry silos, each using its own subject identifier and policy vocabulary.
Now hand that same architecture to your internal or external auditor. The auditor asks a simple governance question: Show me every resource Bob can reach, and prove that an AI agent cannot exercise standing privilege across security domains without an explicit control check.
With one authorization server, you query one entitlement graph. With explicit interactive or step-up domain boundaries, you show the boundary authentication and consent policy in the target IdP. With silent cross-domain token exchange, you have to pull the client registration and token-exchange policy from IDP 1, the routing and transformation policy from the API gateway, the issuer-trust and sub_id mapping rules from IDP 2, and the role assignments from MCP Server Z, and then argue that the intersection of those four configuration stores equals least privilege. No auditor buys that argument without a finding, because nobody on your own team can prove those four stores are in sync on a Tuesday afternoon.
Put the friction back at the boundary and fund consolidation
Criticizing a pattern comes with an obligation to state what you should build instead. You do not have to pretend you only have one IdP tomorrow morning, and you do not have to reject RFC 8693 where it actually belongs. You need four architectural rules that keep a multi-IdP transition state from hardening into a permanent cross-domain vulnerability.
First, keep token exchange inside a single identity provider's trust boundary. When an AI agent receives a delegated token from Microsoft Entra ID and uses the Microsoft identity platform OBO flow or the agent OBO flow in Microsoft Entra Agent ID to call a downstream MCP server registered in the same tenant, one authorization server evaluates both hops. The sub claim has one issuer and one meaning. Conditional Access, continuous access evaluation, risk signaling, and revocation operate on one control plane. That is where OBO and RFC 8693 earn their keep.
Second, never use user-context token exchange when the call is actually autonomous. If a background workload in Domain 1 needs to call an API in Domain 2 without human delegation, authenticate the workload directly to Domain 2 using workload identity federation or certificate-backed JWT client credentials registered in Domain 2. Do not invent a synthetic human sub or chain a stale user token across domains just because a developer found it convenient.
Third, treat every cross-IdP boundary crossing as an explicit security checkpoint, not a background plumbing hop. When a human-initiated flow or an AI agent acting on a user's behalf crosses from IDP 1 into IDP 2, require IDP 2 to evaluate the session at the front door. For an interactive user or supervised agent, let the flow hit an explicit OIDC/SAML federation redirect, a step-up authentication challenge (RFC 9470), or an explicit runtime tool-invocation confirmation. For an asynchronous agent, gate cross-domain elevation behind an explicit access package or time-bound approval workflow rather than silent token exchange. In an era where the 2026 Microsoft Digital Defense Report warns that attackers win by chaining privileges across agents and exploiting excessive agency at machine speed, a deliberate boundary prompt is not bad user experience. It is your circuit breaker.
Fourth, spend your engineering budget on reducing the number of authorization servers, not on building permanent bridges between them. Every cross-domain token exchange pipeline you wire up between IDP 1, your API gateways, and IDP 2 becomes institutional concrete. Once twenty agents depend on IDP 1 minting ID-JAGs or RFC 8693 grants for IDP 2, retiring either IdP becomes twice as hard. Move the target resources (MCP Server Z and the APIs behind it) onto the primary enterprise identity provider on a tracked schedule, following the consolidation discipline in CISA's Zero Trust Maturity Model for identity and Microsoft's application migration guidance.
When someone proposes cross-domain token exchange in your next architecture review, do not just ask whether the JWT signature validates. Ask whether it eliminates dual client registration, dual user lifecycle management, or dual policy administration. Then ask who is going to trace a transcribed sub across three log stores at 2:00 AM when the compromise relationship you just configured gets used the way the protocol designed it to work. If a protocol bridge does not reduce your governance surface and weakens your boundary control, do not build the bridge.
References
- RFC 8693, OAuth 2.0 Token Exchange
- RFC 8693 section 4.1, the act claim
- OAuth Identity and Authorization Chaining Across Domains (draft-ietf-oauth-identity-chaining-17)
- Identity Assertion JWT Authorization Grant (draft-ietf-oauth-identity-assertion-authz-grant-04)
- OAuth Actor Chain: Protocol and Interoperability (draft-mw-oauth-actor-chain-02)
- The industry does not have an agent identity propagation standard yet
- Your API gateway is not an identity provider, and promoting it to one is a liability
- Dynamic client registration and CIMD are not a trust framework
- 2026 Microsoft Digital Defense Report
- 2026 Microsoft Digital Defense Report full PDF
- NIST Special Publication 800-207, Zero Trust Architecture
- What is Zero Trust? Verify explicitly (Microsoft Learn)
- CISA Zero Trust Maturity Model for the identity pillar
- Memo 22-09 enterprise-wide identity management system
- RFC 7523, JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants
- RFC 7519 section 4.1.2, the sub claim
- RFC 9068, JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens
- NIST Special Publication 800-63C-4, Digital Identity Guidelines: Federation and Assertions
- NIST Special Publication 800-63C-4 section 3.3.3, Proxied Federation
- NIST Special Publication 800-63C-4 section 2.3, Federation Assurance Level 3
- NIST Special Publication 800-63C-4 section 3.3.2, Authorized Party
- NIST Special Publication 800-63C-4 section 2.5, Requesting and Processing xALs
- NIST Special Publication 800-63C-4 section 3.4, Federated Identifiers
- RFC 8707, Resource Indicators for OAuth 2.0
- RFC 9396, OAuth 2.0 Rich Authorization Requests
- Microsoft Entra workload identity federation
- RFC 9470, OAuth 2.0 Step Up Authentication Challenge Protocol
- RFC 9449, OAuth 2.0 Demonstrating Proof of Possession (DPoP)
- RFC 7662, OAuth 2.0 Token Introspection
- OAuth Client ID Metadata Document (draft-ietf-oauth-client-id-metadata-document)
- RFC 9493, Subject Identifiers for Security Event Tokens
- Microsoft identity platform on-behalf-of flow
- Agent OAuth flows: on-behalf-of flow in Microsoft Entra Agent ID
- Migrate applications and authentication to Microsoft Entra ID
Top comments (0)