You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Cross-Client Delegation for OAuth 2.0 Token Exchange
Draft response to ID-JAG issue #114 (Architectural Conflict in Gateway / Proxy Topology with Public Clients).
Bottom line. The choice comes down to the gateway's role in your topology. Default to the first; use the second when the gateway is genuinely a fan-out boundary; use the third only when neither is possible:
Recommended — gateway as client. Give the gateway its own user-audienced Identity Assertion, then run base ID-JAG from the gateway (a confidential client). Why the default: lowest mechanism, handles a public agent, needs no audience relaxation. Fits a gateway that reaches a manageable set of upstream services. Getting the gateway its own assertion has two realizations, with a real tradeoff (not just UX):
Silent (cross-client identity) — no prompt, and it carries identity directly from the agent's login; but it needs cross-client issuance, explicit alternate validation for aud=gateway, azp=agent (OpenID Connect Core ordinarily says the receiving client should equal azp), and key binding to the gateway. Prefer it only where the IdP and gateway implement that complete profile.
Interactive (MCP URL elicitation) — the gateway runs its own OIDC login; broadly deployable, but a separate login that must be bound to the same user.
Gateway as RAS + native ICA. When the gateway is a resource boundary that fans out to upstream tools per request — across domains, with pairwise subjects, continuation after the user is gone — model it as a Resource Authorization Server and ICA Chain Authority ("base ID-JAG in, ICA out"). Why not the default: more machinery. Why sometimes necessary: it gives auditable, per-hop continuation with a fresh IdP decision and revocation gate on each further mint.
Fallbacks — CCDR / OAT-in-reverse. Only when the gateway can be neither of the above: a third-party or unregistered gateway that can neither get its own assertion nor be an ID-JAG target. Why last: each carries an open dependency — CCDR's ID-JAG audience-check hook is undefined ("not jointly implementable today"); OAT needs an extension stack and has an open request-binding gap.
So the gist answers #114 for a gateway that can be a first-class OAuth entity, and is an honest gap map for the rest. Start with Agent-to-Gateway Handoff.
Documents
Agent-to-Gateway Handoff (Recommended Approach) — start here. Obtain an Identity Assertion audienced to the gateway and run base ID-JAG from the gateway, a confidential client—no audience relaxation or public-client Token Exchange. The assertion can come from a separate, explicitly linked gateway authorization or from silent cross-client identity issuance.
Gateway OIDC Session via MCP URL Elicitation — the MCP-native interactive bootstrap. It uses current URL mode elicitation, a gateway-owned connect URL, and an authorization code flow. It also defines the same-user binding that prevents one user's elicitation from being completed with another user's account. Device flow and CIBA are optional alternatives, not universal fallbacks.
Gateway as RAS, with Native Identity Continuation — a distinct gateway deployment model: the gateway is a Resource Authorization Server and Identity Continuation Assertion (ICA) Chain Authority — "base ID-JAG in, ICA out" — rather than a client. For a boundary that fans out to upstream tools per request, across domains, with pairwise subjects and user-absent continuation. It complements the recommended handoff (which keeps the gateway a client); it does not replace it.
Token Exchange Profile for Cross-Client Delegation — the primary fallback. Defines the Cross-Client Delegation Relationship (CCDR), actor_token handling, may_act interaction, and act construction, letting a Delegate present the Initiator's assertion under a relaxed audience check. Used when the gateway cannot be issued its own audienced assertion.
ID-JAG Enterprise Broker Deployment Pattern — a deployment of CCDR to the enterprise MDM + gateway topology. Now also Appendix A of the Cross-Client Delegation draft; retained here as the fallback deployment pattern.
Presenter Rebinding for OAuth 2.0 Proof-of-Possession Tokens — the presenter-transition building block. A Presenter Rebinding Assertion (PRA) lets a key-bound token's confirmation-key holder authorize, for one hop, a different key to present that exact token at one authorization server. The base mechanism outputs a DPoP access token; the CCDR fallback defines the explicit ID-JAG output specialization it needs. Full Internet-Draft: Presenter Rebinding.
OAT-in-Reverse: Audience-Preserving Cross-Client Delegation — an alternative considered, not recommended. The Initiator re-mints an assertion audienced to the Delegate, preserving the audience check, at the cost of an extra round trip and an extension stack, and (for a public agent) the same authenticated mint the recommended path avoids.
Reading order
Start with the Agent-to-Gateway Handoff sketch for the recommended approach and how the rest fit around it.
Then the MCP Elicitation sketch for the interactive bootstrap and its identity-linking requirements—the silent form lives in the Handoff sketch.
Then the Gateway-as-RAS + native-ICA sketch for the distinct model where the gateway is a resource boundary that continues identity onward via ICA.
Then the Cross-Client Delegation sketch for the fallback mechanism when the gateway cannot be a related client.
Then the Enterprise Broker deployment pattern for how that lands in the enterprise gateway case.
Then Presenter Rebinding for the one-hop presenter-transition building block the key-bound fallback composes with.
Then the OAT-in-reverse sketch, kept as a documented alternative.
Design-space analysis
The recommended path closes the common case; this section is the map behind it — the two questions the gateway topology raises, and how the fallback mechanisms compare when the recommended path is unavailable.
First handoff — recommended path, and when you fall back
Recommended (the Agent-to-Gateway Handoff sketch): give the gateway its own user-audienced assertion, then run base ID-JAG from the gateway. On the inbound leg the gateway is an OpenID Connect relying party / OAuth client; on the downstream leg it is the ID-JAG client. It is not the upstream Resource Authorization Server. (When the gateway is a resource boundary that fans out per request, model it as a RAS instead — the Gateway as RAS + native ICA sibling topology, treated under the onward chain below.) This handles a public agent because the confidential gateway drives every downstream exchange. The two realizations are not merely a UX choice because only the silent path carries identity directly from the agent's authorization:
Interactive bootstrap (MCP elicitation sketch, or another trusted interaction channel): the gateway runs its own authorization code flow. It requires a registered redirect, a user interaction, and authoritative account linking to the MCP user. Device flow and CIBA depend on IdP support; repeat consent and login behavior are policy-dependent.
Silent (OpenID Connect cross-client identity): no prompt, best UX, but it depends on a cross-client profile that defines alternate azp validation and key-binds the assertion to the gateway — neither yet a clean standard. Prefer it where the IdP and gateway implement the complete profile.
You are in the fallback space only when the gateway cannot get its own assertion at all — a third-party or dynamically provisioned gateway the IdP will neither register as a related client nor let run its own user authorization. Two fallbacks exist, and they are not co-equal:
Dimension
Cross-Client Delegation (CCDR) — primary fallback
OAT-in-reverse — alternative considered
Audience invariant
relaxed under CCDR
preserved
Who drives
the Delegate (gateway)
the Initiator (agent)
Public-agent support
works — the public agent makes no token-endpoint request — but the base mode is bearer and captured-assertion-weak
needs an authenticated public-client mint (the very thing the recommended path avoids)
What it needs
an ID-JAG audience-check exception hook (undefined today); optional Presenter Rebinding plus authenticated Delegate-key distribution for the key-bound strong mode
raised by the relaxation in bearer mode; removed by the Presenter Rebinding composition
moved to a controllable mint; open request-binding gap at the public mint
Claims disclosed to gateway
the agent's full Identity Assertion
a purpose-minimized gateway-audienced assertion
Jointly implementable today
no — needs the ID-JAG hook
no — needs the extension stack
Cross-Client Delegation (CCDR) is the primary fallback: Delegate-driven, so a public agent works without any token-endpoint request from it, and eligibility is an administered relationship between two client registrations. But the base mode is bearer (captured-assertion-weak); the strong mode needs the Presenter Rebinding composition (hence a key-bound ID Token), authenticated distribution of the Delegate key, and an ID-JAG audience-check hook that ID-JAG does not define.
OAT-in-reverse is retained as an alternative considered (its sketch): the agent re-mints an assertion audienced to the gateway. Audience-preserving, but Initiator-driven, needs the extension stack above, and for a public agent needs the same authenticated public-client mint the recommended path sidesteps — so it does not escape the prerequisite it was meant to avoid.
The registered-gateway position
The Enterprise Broker deployment applies CCDR to the enterprise gateway—but the enterprise gateway is exactly the case the recommended path handles, because it can usually be a registered client and obtain its own assertion. So for the enterprise case the own-assertion + base-ID-JAG path is preferred, and CCDR/Broker's real niche narrows to gateways that cannot obtain user identity as themselves (for example, third-party or dynamically provisioned gateways). The Enterprise Broker sketch is retained as that fallback deployment pattern; it is now also Appendix A of the Cross-Client Delegation draft.
Onward chain — the Identity Continuation Assertion
The first handoff gets identity to the gateway. A gateway usually then continues to upstream tools, across trust domains and after the user is gone — a later workload holds none of the user's credentials, and each upstream RAS may name the user with a pairwise subject only the IdP can resolve. The Identity Continuation Assertion (ICA) addresses it: a short-lived, sender-constrained JWT presented to the IdP to mint the next audience-scoped ID-JAG, carrying a continuation handle bound to the root-chain authorization envelope the IdP recorded, so every hop is a fresh IdP policy decision rather than a bearer of standing authority. Its cost is the IdP in the loop at every hop and more moving parts — a Chain Authority, a transaction-token service or trusted carrier, RAS hop-binding — and it is scoped to the same-IdP / IdP-trusting-target case. ICA is the onward answer this gist offers; an offline, no-round-trip onward attenuation mechanism is out of scope here. The Gateway as RAS, with Native Identity Continuation sketch is the concrete deployment of this: the gateway operates ICA's RAS, carrier, and Chain Authority roles — "base ID-JAG in, ICA out" — a different topology from the recommended handoff, where the gateway is a client rather than a RAS.
Presenter Rebinding is one hop, not one use
Presenter Rebinding authorizes a single presenter transition. Its base output is a DPoP-bound access token with no refresh token; CCDR defines an explicit sender-constrained ID-JAG output specialization. One hop does not mean one exchange or one API call: unless a consuming profile requires jti replay tracking, the same PRA can be used again until it expires, and the resulting token follows its own reuse semantics. For long-running or offline work, the interactive gateway can use its own refresh token when IdP policy permits; a separate async-delegation profile such as draft-zhu-oauth-async-delegation is appropriate when standing authority needs separate approval or attenuation. Multi-hop onward uses ICA. presenter_limits narrows only audience; scope, resource, and authorization_details remain entirely dependent on the consuming profile and exchange-time policy.
Choosing
Decide by the gateway's role, in this order:
Is the gateway a fan-out resource boundary — upstream audiences chosen per request, across domains, pairwise subjects only the IdP can resolve, continuation after the user is gone? → Gateway as RAS + native ICA (sketch). Why: it gives each further hop a fresh IdP authorization decision and revocation gate — "base ID-JAG in, ICA out." Already issued access tokens remain valid for their own lifetimes. More machinery, so use it only when the boundary shape actually holds.
Otherwise, can the gateway be its own OAuth client — registered, able to obtain its own assertion? → Recommended: gateway as client (Agent-to-Gateway Handoff): give it a user-audienced assertion, then base ID-JAG. Why the default: lowest mechanism, no audience relaxation, works for a public agent.
Silent (a cross-client profile with alternate azp validation and gateway key binding) — best UX and direct identity continuity, but not unmodified OpenID Connect Core.
Interactive (its own OIDC login, carried by MCP URL elicitation when supported) — portable, but a separate login you must bind to the same user.
Need to cross a later boundary? Add ICA onward (below).
The gateway can be neither — a third-party/unregistered gateway that can't get its own identity → fallbacks. Why last: each has an open dependency. CCDR (Delegate-driven; bearer base mode is captured-assertion-weak, and its ID-JAG composition is not jointly implementable today; add Presenter Rebinding plus authenticated Delegate-key distribution for the key-bound strong mode) or, if you must preserve the audience invariant, OAT-in-reverse (an extension stack, and it still needs an authenticated mint).
Onward chain (any model, when a later hop re-mints identity — pairwise subjects, fresh policy, user gone): the Identity Continuation Assertion — native in the RAS model, added to the client model — with the gateway as Chain Authority.
Provenance
The enterprise deployment shape is derived from @zekth's comment on #114. The generic factor-out came out of subsequent discussion. The OAT-in-reverse alternative inverts the direction of the OpenID Authentication Token Protocol by G. Fletcher.
Status
Sketches for WG discussion. All are informative markdown; Presenter Rebinding and Cross-Client Delegation also have full Internet-Drafts, and the Enterprise Broker pattern is Appendix A of the latter. The interactive recommendation composes OpenID Connect authorization, current MCP URL elicitation where applicable, and base ID-JAG. The silent recommendation additionally needs cross-client identity issuance, alternate azp validation semantics, and gateway key binding. The fallbacks and building blocks remain separable so a deployment adopts only what its topology requires.
Gateway as Resource Authorization Server, with Native Identity Continuation (Sketch)
A deployment model in which the gateway is not an OAuth client reaching across to upstream tools, but a Resource Authorization Server (RAS) and Identity Continuation Assertion (ICA) Chain Authority in its own right — "base ID-JAG in, ICA out." It is exactly the case ICA names: "an API gateway or agent runtime that roots one delegation and continues it to upstream services whose audiences are chosen per request rather than fixed in advance."
This is a different model from the recommended handoff, where the gateway is an OpenID Connect relying party / ID-JAG client and is deliberately not a RAS. Both are valid; use whichever matches the gateway's real role (§5).
1. When this model fits
Use it when the gateway is a genuine authorization boundary in front of a fleet of upstream tools and the onward reach has ICA's shape (ICA's decision rule):
upstream audiences are chosen per request, not a short fixed list the gateway could target directly;
each upstream RAS names the user with an audience-local (pairwise) subject only the IdP can resolve; and
the chain continues after the user is gone, with current policy and chain status re-checked at every onward mint.
When the gateway instead reaches a small, fixed set of upstream audiences it can target directly, the recommended handoff (gateway as client, base ID-JAG per target) is simpler and this model is overkill. ICA's own rule: continuation where a boundary re-mints the subject; direct or offline attenuation where subject and issuer trust stay stable.
2. Roles — the gateway domain operates all three
ICA gives each trust domain three logical roles, and permits one operator to implement all of them. Here the gateway domain does:
RAS — the gateway's authorization server accepts the inbound ID-JAG audienced to it, issues a sender-constrained access token to the presenting agent, and atomically binds the hop (H0) to the accepted authorization.
Trusted carrier / Transaction Token Service (TTS) — inside the gateway domain, the TTS resolves that access token to the bound hop and carries the resulting context to the workload that will call an upstream tool.
Chain Authority (CA) — after rechecking the RAS's accepted authorization state, the CA issues the short-lived, sender-constrained ICA that a workload presents to the IdP to continue to the next audience.
The IdP keeps the roles it never delegates: it owns the root-chain envelope and hop tree, resolves each audience-local subject, and alone authorizes and mints every onward ID-JAG. The IdP creates H0 in a pending state; the gateway RAS records acceptance locally, and the IdP learns of that acceptance only through a fresh assertion from the mapped CA. Critically, the CA never names the user for the upstream audience — only the IdP does. The gateway domain still holds its own RAS authorization state and issued access token; the ICA gives it no independent ability to widen or mint upstream user authority.
3. Flow — base ID-JAG in, ICA out
In (root issuance). The agent is the ID-JAG client and the gateway is the target RAS. The agent authenticates to the IdP, presents the user's root credential, and supplies the DPoP proof ICA requires for a continuation-capable root. The IdP records the root-chain envelope, creates H0 as pending, and returns an ID-JAG audienced to the gateway that contains H0's continuation handle and is bound to the agent's key. (For a public agent, this carries the usual token-endpoint authentication consideration — the same first-handoff question the other sketches address — but from here on the gateway is a RAS, not an upstream client.)
Accept and bind. The agent redeems the ID-JAG at the gateway RAS, authenticates as the client named by the grant, and proves the bound key with DPoP. If the gateway RAS accepts the grant and local policy allows continuation, it atomically binds H0 to the new authorization state and issues a sender-constrained gateway access token to the agent. There is no callback that changes IdP state from pending to accepted.
Carry. The agent invokes the gateway API with that access token and DPoP. The gateway TTS resolves the token against authoritative RAS state and derives H0 into protected intra-domain context for the workload; the agent does not select or supply the handle.
Out (continuation). For a chosen upstream audience, the workload proves its identity and key to the mapped gateway CA. The CA rechecks the accepted H0 authorization and issues an ICA attesting the accepted hop, the current actor, and that key.
IdP mints the next hop. The workload authenticates to the IdP and makes Token Exchange with the ICA as subject_token, a mandatory sender-constrained actor_token, and a DPoP proof for the same key. The IdP validates all three identities and key bindings, resolves H0 against the root-chain envelope, checks the requested target and authority against current policy, and mints ID-JAG(H1) for the upstream RAS, bound to that workload key. The workload redeems it upstream with client authentication and DPoP. A continuation-aware upstream RAS can bind H1 for another hop; a terminal RAS ignores the continuation handle.
Continuation is not bolted onto this gateway; it is how the gateway continues, by construction. Every onward hop is a fresh IdP decision against the envelope: the gateway cannot widen scope, pairwise subjects are resolved by the IdP per audience, and the CA attests accepted hops and actors but never names the user for the target. Revocation or a policy change stops later mints; it does not retroactively invalidate an access token already issued, whose residual exposure lasts until that token expires or is separately revoked. The result is an authorization boundary with auditable per-hop continuation — a property a fan-out gateway needs and that a "gateway holds one broad token and reuses it" model cannot give.
5. Relationship to the other sketches
vs the recommended handoff: that model makes the gateway a client that holds its own user ID Token and reaches upstream RASes directly with base ID-JAG. This model makes the agent the ID-JAG client and the gateway a RAS, then continues onward natively via ICA. Choose the client model for direct reach to a few fixed audiences; choose this RAS + ICA model for a boundary that fans out per request, across domains, with pairwise subjects and user-absent continuation. They compose — the agent→gateway leg is ordinary ID-JAG either way.
vs the CCDR / OAT fallbacks: those relax or re-mint the first handoff's audience check; they are orthogonal to onward continuation and can feed the first hop here.
vs the README onward-chain section: this sketch is the concrete deployment realization of that section's ICA discussion.
6. Security and trust
The IdP owns the envelope, subject resolution, and every mint; no gateway role can name the user for an upstream audience or authorize a target on its own.
The gateway's authority to act as Chain Authority is configured per tenant from authenticated material, not from requester-supplied input.
ICAs are short-lived and sender-constrained; the continuation handle is an opaque IdP reference bound to the recorded hop, not a bearer of standing authority.
Because each onward mint re-checks the envelope, revoking the chain (or a party's permission to continue it) stops future hops. It does not by itself revoke access tokens already issued at prior hops.
Status
Deployment sketch for WG discussion, over ICA. The gateway operates ICA's RAS, carrier/TTS, and Chain Authority roles; the IdP owns the envelope, subject resolution, and every mint. "Base ID-JAG in, ICA out." Distinct from the client-role recommended handoff; the two compose.
The recommended way to solve the ID-JAG issue #114 gateway / proxy topology when an agent hands off to a gateway: don't smuggle the agent's token across a client boundary — issue the user's Identity Assertion audienced to the gateway, and let the gateway (a confidential client) run ordinary ID-JAG downstream. This sketch takes a position; the other sketches in this gist are the mechanisms it recommends, and the fallbacks for when it does not apply.
1. The reframe
The cross-client problem in #114 is largely self-inflicted. ID-JAG's audience check requires the Identity Assertion's audience to equal the authenticated requesting client. If the user's assertion is audienced only to the agent, a different client — the gateway — cannot present it, and you are forced either to relax that check (Cross-Client Delegation) or to re-mint an assertion audienced to the gateway (OAT-in-reverse).
Issue the assertion audienced to the gateway from the start and the problem does not arise: the gateway presents an assertion it is legitimately the audience of, and the base audience check passes unchanged.
There are two ways to get the gateway its own assertion. They reach the same ID-JAG input shape, but they do not provide the same identity-continuity property:
Interactive bootstrap — the gateway runs its own OpenID Connect authorization to obtain its own ID Token; see Gateway OIDC Session via MCP URL Elicitation. This is broadly deployable where the gateway can register a redirect URI, but it is a separate login. The deployment MUST bind the MCP-authenticated user to the account that completes the gateway authorization; otherwise the two accounts may differ. Device flow and CIBA are optional, deployment-dependent alternatives.
Silent — OpenID Connect cross-client identity issues the gateway a user-audienced assertion with no prompt (agent = authorized party azp, gateway = an aud); the flow in §2. Best UX, but it depends on the IdP supporting a cross-client profile with explicit azp validation semantics and on that assertion being key-bound to the gateway. OpenID Connect Core says a client receiving an ID Token with azp should verify that azp equals its own client_id, so aud=gateway, azp=agent is not an unmodified Core validation path. A plain cross-client ID Token is also a bearer token, making key binding (OpenID Connect Key Binding) an added requirement. Neither extension is yet a clean standard.
Prefer the silent path where the IdP offers both. Use the interactive path as a separately authorized, explicitly linked gateway session—not as proof that the agent's login was handed off. §2 details the silent flow; the elicitation sketch details the interactive flow and its same-user binding requirement.
Prerequisites: the agent and gateway are registerable at the IdP as related clients; the gateway is a confidential client with a registered key; the IdP and gateway implement an explicit cross-client validation profile for azp; and the IdP will key-bind the gateway-audienced assertion (also not standard behavior — see §1). This holds for the enterprise agent+gateway case #114 motivates, where one enterprise operates both, when the IdP supports those extensions.
Register the relationship so the agent's authentication may yield user identity for the gateway (agent = azp, gateway = aud).
The user authenticates through the agent (authorization code + PKCE). PKCE binds authorization-code redemption to the client instance that initiated the request; it does not turn a public client into an authenticated client. There is no separate public-client Token Exchange in this flow.
The IdP issues an Identity Assertion audienced to the gateway (aud = gateway, azp = agent), sender-constrained to the gateway's registered key. The agent conveys it to the gateway when it invokes it. (Alternatively the agent calls the gateway with a normal access token and the gateway obtains its own gateway-audienced assertion — the async-delegation delegation-handle path.)
The gateway runs ID-JAG. As a confidential client authenticating normally, it presents the gateway-audienced assertion as subject_token and requests a downstream grant for each upstream Resource Authorization Server (RAS). ID-JAG's audience check passes because the gateway is the assertion audience — no audience relaxation, OAT extension, or public-client Token Exchange is needed. The silent cross-client issuance profile nevertheless has to define why the gateway accepts azp=agent instead of applying OpenID Connect Core's ordinary azp check. ID-JAG carries client continuity through its client authentication and downstream client_id mapping; it does not automatically construct an act claim.
Because the assertion is bound to the gateway's own key, the gateway proves possession directly — there is no presenter transition and no need for Presenter Rebinding. Rebinding is only for the fallback case where a client must present a token bound to a key it does not hold.
3. Continuation and onward hops
Offline / long-running: in the interactive path, the gateway can request its own refresh token (for example with offline_access) when IdP policy permits. Base ID-JAG also permits a refresh token bound to the authenticated gateway as subject_token. Use an async-delegation profile when standing authority needs a separate approval, attenuation, or lifecycle rather than merely to obtain the gateway's ordinary refresh token.
Multi-hop onward, across trust domains and after the user is gone → the Identity Continuation Assertion, with the gateway as Chain Authority.
Actor semantics: the authenticated client and the actor are distinct concepts. Base ID-JAG does not define actor_token processing or automatically emit act = gateway. A companion actor-delegation profile may define an act claim and any prior-actor chain; those claims are informational under RFC 8693 §4.1, not an authorization input at the protected resource.
4. Why this is the recommendation
No ID-JAG audience relaxation. Once the gateway has its own assertion, the ID-JAG audience check is unchanged. The interactive realization composes ordinary OpenID Connect authorization with base ID-JAG. The silent realization additionally depends on cross-client issuance, its alternate azp validation semantics, and third-party key binding; those are deployment features, not behavior supplied by base ID-JAG.
No public-client Token Exchange. In the silent path, the gateway-audienced assertion is issued during the agent's authorization. In the interactive path, the gateway obtains it in its own authorization. In both cases the confidential gateway drives the downstream exchange.
Clean attribution. The gateway holds its own credentials and, for continuation, its own refresh-token family: revocation, rotation, and lifecycle are all attributable to the gateway rather than borrowed from the agent.
5. Hardening the handoff
In the silent path the one artifact crossing the wire is the gateway-audienced assertion. Bind it to the gateway's registered key and keep it short-lived: a capture in transit is then inert, because only the gateway can present it. This binding is not automatic — a plain cross-client ID Token is a bearer token, so the IdP needs an agreed mechanism to bind the assertion to the gateway's registered key. In the interactive path there is no conveyed assertion: the gateway receives and stores its own ID Token directly. Client authentication alone does not key-bind an ID Token, but no presenter transition is needed; the normal ID-JAG audience check and gateway client authentication apply.
6. When this does not apply — fallbacks
Reach for the harder mechanisms only when the gateway cannot be issued its own audienced assertion — a third-party or dynamically provisioned gateway the IdP will not register as a related client or issue user identity for:
Cross-Client Delegation — an administered relationship (CCDR) lets the gateway present the agent's assertion under a relaxed audience check. Delegate-driven; for the key-bound case it composes with Presenter Rebinding.
OAT-in-reverse — the agent re-mints an assertion audienced to the gateway, preserving the audience check at the cost of an extra round trip and an extension surface.
Both are heavier and, per those sketches, not fully implementable today. Prefer the recommended path—an explicitly linked interactive session or silent cross-client identity—whenever the gateway can obtain its own assertion.
7. Realizations and their prerequisites
The two realizations differ in how the gateway gets its own assertion and how identity continuity is established:
Interactive is the standards-based default where the gateway can register and receive a redirect. It creates a separately authorized gateway session and therefore needs authoritative same-user/account linking. Consent and reauthentication frequency are policy-dependent, and neither client authentication nor PKCE automatically key-binds the resulting ID Token. Over MCP, current URL mode elicitation carries the interaction.
Silent needs the IdP and gateway to support cross-client issuance with explicit alternate azp validation semantics and to key-bind the gateway-audienced assertion — features not yet clean standards. Where present it is the better UX, with no prompt.
Standardizing a compact way to request "an Identity Assertion audienced to related client X, bound to X's registered key," including how the initiating client is represented and validated without conflicting with Core azp processing, is the smallest missing piece that would make the silent form turnkey. The interactive form is available where a separate, linked gateway authorization is acceptable. You fall back to §6 only when the gateway cannot obtain its own assertion by either means.
Status
Recommendation sketch for WG discussion. The interactive path composes OpenID Connect authorization and base ID-JAG but requires explicit same-user binding. The silent path additionally depends on cross-client identity issuance, alternate azp validation semantics, and gateway key binding. The other sketches cover continuation (async-delegation, ICA) and fallbacks.
Status: fallback deployment pattern. This applies the Cross-Client Delegation (CCDR) profile to the enterprise gateway. Where the enterprise gateway can be a registered client at the IdP and obtain its own assertion—the common case when one operator controls both—prefer the Agent-to-Gateway Handoff recommendation (gateway-audienced assertion + base ID-JAG), which needs no audience relaxation. This pattern is for when the gateway cannot be issued its own user-audienced assertion. It is now also Appendix A of the Cross-Client Delegation Internet-Draft, which is authoritative where the two differ.
Abstract
This document describes the "Enterprise Broker" deployment pattern for ID-JAG
Token Exchange. In this pattern, a confidential gateway (the Broker) obtains
an ID-JAG following an invocation from a centrally-administered initiating
client (the Managed Client), which is commonly a public native or command-
line client. The IdP maintains a Cross-Client Delegation Relationship (CCDR)
between the two client registrations.
The pattern is an instantiation of the generic Cross-Client Delegation profile
for OAuth 2.0 Token Exchange
(Cross-Client Delegation Profile), applied to ID-JAG.
That profile, rather than this document, defines the normative exception to
ID-JAG's default Identity Assertion audience check.
This document is informative. It describes the additional deployment controls
needed around the generic CCDR mechanics, including authenticated handoff,
request correlation, Resource Authorization Server client mapping, and key
binding. It also provides a citable reference for the Enterprise Broker case
in ID-JAG issue discussion.
1. Deployment Context
Enterprise deployments of agent-plus-gateway topologies increasingly exhibit
a common shape:
The initiating client (typically an agent) is distributed via Mobile Device
Management (MDM) or a comparable enterprise deployment channel.
Every install of the agent receives the same centrally-administered
client_id. The client_id identifies the managed software registration;
it is not a secret and does not authenticate an individual installation.
Each End-User signs into the IdP via the agent using an Authorization Code
flow with PKCE (RFC 7636), producing an Identity Assertion whose aud
equals the pinned agent client_id and whose sub is per-user.
When supported by the deployment, the same authorization produces an
access token for invoking the Broker. That access token identifies the
Managed Client and End-User and can be sender-constrained to an instance
key.
The agent invokes a gateway (the Broker) to reach one or more upstream
Resource Authorization Servers.
The gateway is a distinct confidential OAuth client, administered by the
same enterprise IT that provisioned the agent.
Under base ID-JAG rules, the Broker cannot obtain an ID-JAG on the End-User's
behalf: the ID Token's audience is the Managed Client, not the Broker, and
the ID-JAG Token Exchange audience check rejects the exchange. The generic
Cross-Client Delegation profile defines a policy-controlled exception for an
authorized client pair. This document describes the enterprise deployment
controls surrounding that exception.
2. Why the Enterprise Case Is Eligible for CCDR
The base ID-JAG audience check ensures that an Identity Assertion is presented
only by its intended client. It prevents cross-client presentation regardless
of how either client was registered.
The Enterprise Broker pattern deliberately replaces literal audience equality
with a narrower policy decision over a client pair:
The IdP has established that the Managed Client registration is eligible
to participate in this deployment, whether it was created statically or
through an appropriately authorized registration process.
The IdP has established and can authenticate the Broker as a confidential
OAuth client.
The IdP maintains an administered Cross-Client Delegation Relationship
(CCDR) authorizing the Broker to act on behalf of the Managed Client.
The Broker accepts the Identity Assertion only as part of an authenticated
and correlated invocation from the Managed Client.
These controls authorize a known Broker to present an assertion issued for a
known Managed Client. They do not prove, merely from the ID Token audience or
the CCDR, that the Managed Client conveyed a particular assertion. They also
increase the utility of a captured Identity Assertion. The authenticated
handoff and replay controls described below are therefore part of the
deployment pattern, not optional consequences of static registration.
3. Actors
Managed Client
: An initiating OAuth client whose registration is administered or approved
by the IdP and distributed via MDM or a comparable channel with a pinned
client_id. It is commonly a public client. Users sign in through the
Managed Client and receive Identity Assertions.
Broker
: A confidential OAuth client that mediates access to upstream Resource
Authorization Servers. The Broker authenticates the Token Exchange request
to the IdP.
Cross-Client Delegation Relationship (CCDR)
: The administered relationship linking a Managed Client to one or more
Brokers. The IdP maintains the relationship as canonical policy and may
expose read-only client metadata views such as authorized_delegates on
the Managed Client and delegate_of on the Broker.
End-User
: The subject of the delegation. Authenticates once through the Managed
Client.
4. Flow
The End-User authenticates the Managed Client at the IdP via
Authorization Code + PKCE. The Managed Client receives:
an ID Token with aud = managed-client-id, sub = user, and
optionally a may_act claim identifying the Broker; and
when supported, an access token for invoking the Broker.
The Managed Client invokes the Broker and conveys the ID Token within that
request. The Broker authenticates the invocation, validates the
Broker-audience access token or equivalent request credential, and
correlates it with the ID Token as described in
§6.
The Broker performs Token Exchange at the IdP per the Cross-Client
Delegation profile:
subject_token: the ID Token.
actor_token: a credential establishing the Broker as the actor.
client authentication: the Broker authenticates as itself.
audience: the issuer identifier of the target Resource Authorization
Server.
resource, scope, and authorization_details as appropriate for the
target protected resource.
when requesting a sender-constrained ID-JAG, a DPoP proof of the Broker
key to which the ID-JAG will be bound.
The IdP validates the CCDR, confirms may_act if present, evaluates
fresh policy over (User, Managed Client, Broker, target audience, resource, scope, authorization_details), resolves the Broker's client
identifier at the target Resource Authorization Server, and issues an
ID-JAG with act identifying the Broker.
The Broker presents the ID-JAG at the target Resource Authorization
Server per base ID-JAG, authenticating under the client identifier carried
by the ID-JAG and proving possession of the bound key when the ID-JAG is
sender-constrained.
For example, the Token Exchange request includes the following form body and,
when sender constraining is used, a DPoP HTTP header proving the Broker key:
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&requested_token_type=urn:ietf:params:oauth:token-type:id-jag
&subject_token=<Managed Client ID Token>
&subject_token_type=urn:ietf:params:oauth:token-type:id_token
&actor_token=<Broker actor credential>
&actor_token_type=urn:ietf:params:oauth:token-type:jwt
&audience=https://authorization-server.example/
&resource=https://api.example/
&scope=tool.invoke
The Managed Client is not automatically included as a nested prior actor.
The ID Token audience and CCDR establish the client relationship, not proof
that the Managed Client actively authorized this particular handoff. A
nested Managed Client is appropriate only when the selected handoff mechanism
satisfies the authenticated prior-actor requirements of the Cross-Client
Delegation profile.
5. Trust Model
The authorization decision rests on three facts the IdP itself administers:
The Managed Client registration is eligible to participate in the
enterprise deployment and is one endpoint of the CCDR.
The Broker registration is the other endpoint of the CCDR, and the Broker
is authenticated on the Token Exchange request.
The CCDR authorizes this specific Broker to act for this specific Managed
Client.
These facts allow the IdP to replace literal
aud == authenticated client_id equality with an explicit policy check over
the (Managed Client, Broker) pair. They establish eligibility, not proof of
a particular handoff and not entitlement to arbitrary audiences, resources,
scopes, or authorization details.
Within the single-IdP scope of this pattern, the IdP re-checks at each mint
that the Managed Client and the Broker registrations are enabled and the CCDR
still authorizes the pair, per the Cross-Client Delegation profile (see
Cross-Client Delegation Profile, §11.9). A prior actor recorded only
in a nested act chain is not an authorization input and is not part of this
check. Revocation of the Managed Client or the Broker propagates through the
mint-time check; a token already issued cannot be revoked retroactively, and
short exp values on issued tokens bound the residual window.
The pattern intentionally increases the value of an Identity Assertion
captured in transit or compromised at the Broker. Its security therefore also
depends on the Broker enforcing the authenticated handoff rules, short
assertion lifetimes and replay policy, narrowly scoped CCDRs, and sender
constraining where the presenter-transition problem has been addressed.
This trust model does not itself establish End-User consent. See
§8.
6. Authenticated Handoff and Correlation
The CCDR authorizes a client pairing but does not demonstrate that the
Managed Client conveyed a particular ID Token to the Broker. This deployment
pattern therefore expects the ID Token to arrive within an authenticated
Broker invocation.
Where the Managed Client presents an access token for the Broker, the Broker
validates that token according to its type and local policy and correlates it
with the accompanying ID Token. Correlation includes, where available:
the same validated IdP issuer or a configured issuer relationship;
the same End-User subject, or a trusted mapping between the subject
identifiers in the two tokens;
a client_id or equivalent authorized-party value identifying the Managed
Client registration that is the Initiator endpoint of the CCDR;
compatible authentication time, session, tenant, and authorization
context; and
proof of the same Managed Client instance key when the invocation and
Identity Assertion support a common sender constraint.
The Broker rejects an invocation when the request credential and ID Token
cannot be correlated at the assurance required by deployment policy. The
Broker does not treat claims from the ID Token as authorization for the
upstream resource before the IdP has successfully performed the ID-JAG Token
Exchange.
An RFC 8693 may_act claim naming the Broker provides per-assertion actor
authorization and further narrows the CCDR. It does not, by itself,
authenticate the transport or prove that the Managed Client initiated a
particular request.
Deployments unable to authenticate and correlate the handoff operate in a
weaker relationship-only bearer mode. Such deployments need to document that
capturing any eligible Managed Client ID Token may be sufficient for an
authorized Broker to obtain an ID-JAG, and should apply correspondingly short
lifetimes, one-time-use or replay controls, narrow CCDRs, and constrained
downstream grants.
7. What This Pattern Does Not Cover
This pattern is deliberately narrow. It does not apply to:
Unadministered client registrations. The registration mechanism is not
decisive: static registration alone is insufficient, and Dynamic Client
Registration is not automatically disqualifying. The base ID-JAG audience
check applies unless the IdP has established through an administrative or
otherwise trusted process that both registrations may participate in the
specific CCDR.
Public clients acting as Brokers. The Broker must be a confidential
client. The Managed Client may be public; public clients presenting their
own ID Tokens directly are the base ID-JAG case rather than this pattern.
Cross-organizational Brokers. When the Broker and the Managed Client
are controlled by different organizations, establishing the CCDR requires
trustworthy onboarding, identifier namespacing, credential validation, and
administrative authority. Those mechanisms are outside this pattern,
although a single IdP may recognize such a Broker once that trust has been
established.
Autonomous (no-user-present) invocations. The pattern assumes an
Identity Assertion the Managed Client obtained on the End-User's behalf.
Deployments where the Managed Client operates without a user session
(scheduled tasks, background workers) require a different mechanism.
Uncorrelated bearer forwarding as a high-assurance handoff. Merely
placing an ID Token in a request does not authenticate the Managed Client's
participation. Relationship-only bearer deployments have the limitations
described in §6.
Cross-trust-domain revocation propagation. The mint-time re-check of
enabled registrations and the CCDR is tractable within a single IdP (this
pattern). When a delegation spans organizations, checking a remote party's
current status requires reaching another authority; and a chain whose every
link must be revocable belongs in a purpose-built structure rather than
act (see Cross-Client Delegation Profile, §11.9). That constraint is
the cold-start gap tracked in the use-cases repo (issues #17 and #18).
8. Consent Semantics
Neither the CCDR nor a may_act claim by itself establishes that the
End-User understood or approved disclosure to the Broker. Enterprise
deployments may rely on:
Consent or disclosure during Managed Client authentication that expressly
covers the Broker relationship.
Administrative authorization as the trust basis for the CCDR.
Another applicable contractual, legal, or organizational policy basis.
Deployments should reflect delegation to Brokers in user experience where
appropriate and need an applicable consent, enterprise-policy, or other
authorization basis for the pattern to be lawful and legible in their
context. This document does not define a user-consent event or assume that
ordinary OIDC authentication consent extends to the Broker.
9. Composition With Base ID-JAG
This composition is not jointly implementable today. It requires ID-JAG to
define an audience-check exception point that the generic
Cross-Client Delegation
profile can substitute its CCDR check into, and ID-JAG does not yet define one
(see Cross-Client Delegation §12.3).
The pattern below describes the intended composition; building it from the
specifications as written depends on that ID-JAG extension. Everything else in
this pattern is additive over base ID-JAG and does not modify base ID-JAG
processing rules for cases outside its scope. Specifically:
Base ID-JAG's audience check applies unchanged where no CCDR exists.
The generic Cross-Client Delegation profile defines the CCDR-authorized
exception to that check. This informative deployment pattern does not
independently override the base requirement.
The issued ID-JAG's structure, target-specific subject resolution, tenant
context, and downstream presentation to the Resource Authorization Server
follow base ID-JAG.
The ID-JAG client_id identifies the Broker's client registration at the
target Resource Authorization Server, because the Broker will authenticate
under that registration when redeeming the ID-JAG.
The Broker's client_id at the IdP, the Broker's client_id at the
Resource Authorization Server, and the Managed Client's client_id at the
IdP may all differ. The IdP needs a trusted mapping from the authenticated
Broker to the target-side Broker registration.
The ID-JAG sub and related subject or tenant claims identify the
End-User in the namespace expected by the target Resource Authorization
Server, rather than blindly copying an Initiator-scoped pairwise subject.
When the ID-JAG is sender-constrained, its cnf binds the ID-JAG to a
Broker-controlled key that the Broker proves when redeeming it.
The CCDR-authorized relaxation applies only to the audience check on the
Identity Assertion at Token Exchange time, and only when the Cross-Client
Delegation profile's processing rules are followed.
10. Composition With Other Profiles
Cross-Client Delegation profile
(Cross-Client Delegation Profile): this pattern is
an application of that profile. All mechanics (CCDR administration,
actor_token handling, act claim construction, may_act interaction)
follow the generic profile.
draft-mcguinness-oauth-actor-profile: the act claim in the issued
ID-JAG follows the Actor Profile for Delegation when that profile is used.
The Broker is the current actor. The Managed Client is not automatically a
nested prior actor.
OpenID Connect Key Binding 1.0: key-binding the Identity Assertion is
strongly recommended in this pattern because the CCDR-authorized
relaxation raises the value of a captured Identity Assertion. Because the
base Cross-Client Delegation profile excludes key-bound assertions, this
requires the optional composition with
Presenter Rebinding: the Managed Client
(Original Presenter) signs a one-hop assertion authorizing the Broker's key to
present that exact Identity Assertion. It does not require or permit transfer
of the Managed Client's private key. The deployment must also provide the
authenticated, integrity-protected mechanism by which the Managed Client
obtains the Broker key and binds it to the intended Broker registration;
Presenter Rebinding does not define that key-distribution step.
draft-ietf-oauth-attestation-based-client-auth: client attestation can
authenticate a particular Managed Client or Broker instance and prove
possession of an instance key. It complements rather than replaces the
CCDR: attestation establishes instance authenticity, while the CCDR
authorizes the cross-client relationship. See related discussion in
ID-JAG issue #114.
11. Provenance
One observation motivating this pattern was contributed to ID-JAG issue #114
by GitHub user zekth: an MDM-pinned Managed Client and an
administratively-linked Broker give the IdP enough policy context to evaluate
a narrowly-scoped cross-client exchange. The same comment explicitly notes
that the relaxation raises the value of a captured Managed Client ID Token.
This document generalizes the deployment observation, makes the residual
handoff risk explicit, and connects the pattern to the generic Cross-Client
Delegation profile.
Original discussion:
ID-JAG issue #114 (Architectural Conflict in Gateway / Proxy Topology
with Public Clients).
Gateway OIDC Session via MCP URL Elicitation (Sketch)
This is the interactive bootstrap for the Agent-to-Gateway Handoff: the gateway runs its own OpenID Connect authorization and then uses its own Identity Assertion in base ID-JAG. This is not a cryptographic continuation of the agent's login. Unless the deployment binds the two identities as described below, the user could authenticate a different account at the gateway.
Over MCP, the appropriate user-interaction mechanism is URL mode elicitation. URL mode is specifically intended for an MCP server acting as an OAuth client to a third-party service. It is separate from the OAuth authorization between the MCP client and MCP server.
1. Setting and prerequisites
The MCP client/host is an enterprise-managed agent that calls a gateway implemented as a remote MCP server. The gateway needs an Identity Assertion for an upstream Resource Authorization Server (RAS).
The gateway MUST:
be a registered OAuth client at the IdP, with a registered redirect URI and client-authentication method;
derive the initiating user's identity from authoritative MCP authorization credentials, when available, rather than from client-supplied input;
maintain a protected, single-use transaction bound to the initiating MCP client, authenticated user, and tool request; and
use this pattern only when the MCP client advertises URL elicitation support in _meta.io.modelcontextprotocol/clientCapabilities.elicitation.url. An empty elicitation capability means form mode only and is insufficient for this flow.
2. Authorization code flow
The MCP client invokes a tool on the gateway.
The gateway creates an opaque, expiring handoff handle. Server-side state binds that handle to the initiating MCP principal, MCP client, original request, PKCE verifier, OAuth state, and OIDC nonce.
The gateway returns an InputRequiredResult containing a URL mode elicitation/create request. The URL is a gateway-controlled HTTPS connect URL, not the IdP authorization endpoint:
{
"method": "elicitation/create",
"params": {
"mode": "url",
"url": "https://gateway.example/connect?h=opaque-single-use-handle",
"message": "Connect your account so the gateway can call the requested service."
}
}
After explicit user consent, the MCP client opens the URL without prefetching it or exposing the resulting page to the model.
The connect endpoint verifies that the browser user is the same authoritative user who initiated the MCP request—for example, by comparing the MCP authorization subject with a gateway web-session subject. It then redirects to the IdP authorization endpoint with response_type=code, scope=openid, PKCE, state, nonce, and the gateway's registered redirect_uri.
The IdP redirects the authorization response to the gateway. The gateway validates the response, redeems the code using its client authentication and PKCE verifier, and validates the ID Token.
The gateway binds the resulting IdP account to the initiating MCP principal. If their subject namespaces differ, the deployment needs an authoritative account-link mapping or an explicit account-linking ceremony. A login_hint, e-mail address, or unverified client assertion is not sufficient. An unexpected account MUST be rejected or explicitly reconciled.
The client retries or resumes the original request. For URL mode, { "action": "accept" } records consent to open the interaction; it does not report that OAuth completed. The gateway determines completion from its protected transaction state and otherwise returns another InputRequiredResult or a pending result.
Agent -> Gateway: tools/call (MCP authorization identifies initiating user)
Gateway -> Agent: URL elicitation (gateway connect URL)
Agent -> User: show domain and request consent; open URL
User -> Gateway: connect URL (gateway verifies same initiating user)
Gateway -> IdP: authorize (code, openid, PKCE, state, nonce)
IdP -> Gateway: redirect with code
Gateway -> IdP: token request (code, verifier, client authentication)
IdP -> Gateway: ID Token (aud=gateway, sub=linked user)
Agent -> Gateway: resume original tools/call
Gateway -> IdP: base ID-JAG (subject_token=ID Token, audience=RAS)
Gateway -> RAS: present ID-JAG
3. Device Authorization Grant and CIBA
Device Authorization Grant and CIBA can provide alternative user experiences, but neither is a universal fallback:
OAuth Device Authorization Grant does not itself specify OpenID Connect ID Token issuance. A deployment must verify that its IdP supports openid in that flow and returns a suitable ID Token.
CIBA is a separate OpenID Connect profile that the IdP must support.
Both still need a phishing-resistant way to bind the user completing the out-of-band interaction to the authoritative user who initiated the MCP request. Displaying a verification_uri or accepting a CIBA completion is not, by itself, that binding.
A gateway can use a gateway-controlled connect URL to establish the binding before beginning either flow. The device_code, authorization code, tokens, and credentials MUST remain outside MCP.
4. Base ID-JAG and continuation
The gateway presents its own ID Token as the subject_token and authenticates as itself. Base ID-JAG validates that the assertion audience matches the authenticated request client's client_id; no cross-client audience exception is needed.
Base ID-JAG does not automatically issue act = gateway. The gateway's OAuth client identity is represented through client authentication and the downstream client_id mapping. An act claim is present only when a separate actor-delegation profile defines the actor-token processing and claim construction.
For later use, the gateway can request its own refresh token during its authorization when the IdP permits offline_access, or it can use a separate async-delegation profile when standing delegated authority requires an additional approval or attenuation step. Base ID-JAG also permits an IdP-bound refresh token as subject_token. Multi-hop continuation is a separate problem; see the Identity Continuation Assertion.
5. Security properties and limitations
The connect URL MUST contain only an opaque, short-lived, single-use handle—not user identity, credentials, tokens, or a pre-authenticated session.
The MCP client MUST show the target domain, obtain consent before navigation, avoid prefetching, and open the URL where neither the client nor model can inspect user input.
OAuth state, OIDC nonce, and PKCE bind protocol messages to the transaction; they do not prove that the person completing the browser flow is the initiating MCP user. The connect-session check and account binding supply that missing property.
The gateway stores and manages the tokens. It MUST NOT return them to the MCP client or use the MCP client's third-party credentials as token passthrough.
Reauthorization and consent frequency are IdP policy decisions. “One-time bootstrap” is a deployment goal, not a protocol guarantee.
6. Applicability
Authorization code flow is the standards-based default where the gateway can register and receive an HTTPS redirect and the client supports MCP URL elicitation. Device flow and CIBA are deployment-dependent alternatives. If the client lacks URL mode, the gateway needs another trusted user-interaction channel; form mode MUST NOT be used to collect credentials, authorization codes, or tokens.
This interactive path gives the gateway a separately authorized session for a linked user. The silent cross-client-identity path instead carries identity from the agent's authorization without another prompt, but requires IdP support, explicit cross-client azp validation semantics, and a secure mechanism for issuing an assertion usable only by the gateway. Both satisfy the ID-JAG audience check, but only the interactive path uses unmodified OpenID Connect Core ID Token validation; they do not have identical identity-continuity properties.
Status
Sketch for WG / MCP discussion. It tracks MCP draft URL mode elicitation (introduced in protocol version 2025-11-25) and base ID-JAG -04.
Status: alternative considered—not the recommended path. For the agent→gateway case, prefer the Agent-to-Gateway Handoff recommendation (gateway-audienced assertion + base ID-JAG), or the Cross-Client Delegation profile as the primary fallback. This sketch is retained as a documented dual: audience-preserving, but Initiator-driven, dependent on a stack of extensions, and—for a public agent—still needing the same authenticated mint the recommended path avoids (§11.2, §13).
Abstract
This sketch describes an alternative to the Token Exchange Profile for Cross-Client Delegation for the same gateway / proxy problem (ID-JAG issue #114). Rather than letting a Delegate present the Initiator's Identity Assertion under a relaxed audience check authorized by a Cross-Client Delegation Relationship (CCDR), the Initiator mints an assertion audienced to the Delegate and conveys that. Every Token Exchange in the flow keeps the requester as the subject token's audience, so the RFC 8693 / ID-JAG audience invariant is never relaxed. The downstream exchange still needs one ID-JAG change — accepting the Delegate-Audienced OAT as a redeemable subject_token — but that is a subject-token-type extension, not the audience-check exception the CCDR approach depends on. The gain is eliminating the audience relaxation, not eliminating every ID-JAG dependency.
The intermediate assertion is an OpenID Authentication Token (OAT) audienced to the Delegate. It is "OAT-in-reverse" because OAT's move — a Relying Party exchanging its ID Token for an OP-signed assertion audienced to another party — is aimed inward at the Delegate (the gateway) rather than outward at a peer Relying Party. The extension surface is modest but not a single change: Exchange B is OAT issuance; Exchange E requires ID-JAG to accept the OAT as a redeemable subject_token (a subject-token-type extension, not the audience-check exception the CCDR approach needs); and the mint additionally needs third-party cnf selection and a Mint Authorization. The full surface is enumerated in §7 and §12.
1. Introduction
An enterprise agent (a public, MDM-distributed client) authenticates the End-User and receives an ID Token whose audience is the agent. A confidential gateway — a different OAuth client — must reach upstream Resource Authorization Servers on the End-User's behalf. Under base ID-JAG the gateway cannot obtain a grant from the agent's ID Token, because the assertion's audience is the agent, not the gateway.
The Cross-Client Delegation sketch resolves this by relaxing the audience check for an administered client pair. That relaxation is the mechanism's power and its principal risk: the same comment on #114 that motivated it noted that relaxing the check raises the value of a captured Identity Assertion.
This sketch resolves the same problem without relaxing anything. Because the Initiator is the audience of its own ID Token, it can exchange that ID Token — an ordinary, audience-preserving operation — for an OAT audienced to the Delegate. The Delegate then holds a token it is legitimately the audience of, and its downstream ID-JAG exchange passes the base audience check with no exception. The trust decision moves from "relax an audience check at presentation time" to "authorize a mint at issuance time," while the authenticated Initiator is present.
Like Cross-Client Delegation, this is a fallback: it applies when the gateway cannot be issued its own user-audienced assertion. Where the gateway can be a registered client and obtain its own assertion, the Agent-to-Gateway Handoff recommendation (gateway-audienced assertion + base ID-JAG) is simpler and needs neither a re-mint nor the extension surface below.
1.1 Applicability and Non-Goals
This mechanism applies where the Initiator can perform a Token Exchange before conveying anything to the Delegate, and where the Delegate can be identified as an audience and can prove possession of a key. In the agent-plus-gateway topology the agent already initiates the interaction, so the additional exchange fits the flow.
Non-goals:
Mint-authorization enrollment. How the authorization server is configured to permit an Initiator to mint for a Delegate is a deployment concern, exactly as CCDR establishment is in the Cross-Client Delegation sketch.
Cross-organizational Delegates. Recognizing a Delegate administered by a different organization is out of scope.
Autonomous operation. The mechanism assumes an ID Token the Initiator obtained on the End-User's behalf; no-user-present flows need a different mechanism.
End-User consent UX. How delegation to the Delegate is surfaced to the End-User is a deployment concern subject to applicable policy.
Replacing Cross-Client Delegation. This is offered as a dual, not a replacement; see §10.
2. Terminology
Initiator
: The OAuth client that authenticated the End-User and holds an ID Token whose audience is the Initiator. Commonly a public, MDM-pinned client (the agent).
Delegate
: The confidential OAuth client that acts on the End-User's behalf downstream (the gateway or Broker). It is the audience of the intermediate assertion and its presenter.
IdP
: The authorization server that issued the ID Token and performs both Token Exchanges.
Resource Authorization Server (RAS)
: The upstream authorization server the Delegate reaches with the downstream grant.
Delegate-Audienced OAT
: The intermediate assertion. An OpenID Authentication Token whose aud is the Delegate and whose cnf is a key the Delegate controls, minted by the Initiator in Exchange B and redeemed by the Delegate in Exchange E.
Mint Authorization
: An authorization-server-administered eligibility rule permitting an Initiator to mint a Delegate-Audienced OAT for a given Delegate. It is the dual of the CCDR: where a CCDR authorizes a Delegate to present an Initiator's assertion, a Mint Authorization authorizes an Initiator to mint an assertion for a Delegate.
Exchange B
: The mint. The Initiator exchanges its ID Token for a Delegate-Audienced OAT.
Exchange E
: The redemption. The Delegate exchanges the Delegate-Audienced OAT for a downstream grant (an ID-JAG).
The End-User authenticates the Initiator at the IdP. The Initiator holds an ID Token with aud = Initiator. The ID Token SHOULD be key-bound, and MUST be when the Initiator is a public client (see §11.2).
The Initiator learns the Delegate's proof-of-possession key, for example from the Delegate's response when the Initiator first invokes it.
Exchange B (mint). The Initiator performs a Token Exchange at the IdP: subject_token is its own ID Token; audience is the Delegate; requested_token_type is the OAT type; and the request conveys the Delegate's key as the cnf to bind. The IdP authenticates the Initiator (client credentials for a confidential Initiator, or a key-bound ID Token plus proof of its cnf key for a public one; see §11.2), checks the ordinary audience rule (the assertion's audience is the requester), evaluates the Mint Authorization for the pair, and issues a Delegate-Audienced OAT sender-constrained to the Delegate's key.
The Initiator conveys the Delegate-Audienced OAT to the Delegate.
Exchange E (redeem). The Delegate performs a Token Exchange at the IdP: subject_token is the Delegate-Audienced OAT; requested_token_type is urn:ietf:params:oauth:token-type:id-jag; audience is the RAS. The Delegate authenticates as its client and proves the OAT's cnf key. Because the OAT's audience is the Delegate and the Delegate is the requester, the base ID-JAG audience check passes unchanged. The IdP issues an ID-JAG with act identifying the Delegate.
The Delegate presents the ID-JAG at the RAS per base ID-JAG.
The Initiator (agent-client) MAY appear as a nested prior actor when the IdP authenticated its participation in the mint; see §9.
4. The Delegate-Audienced OAT
The intermediate assertion is an OpenID Authentication Token with two differences from the base OAT profile, described below. Aligning the intermediate with OAT reuses an existing token type rather than defining a new one; the full extension surface this entails is summarized in §7, and the alternative of a purpose-built grant is noted in §13.
4.1 Claims
Beyond the OAT-defined claims (iss, sub, aud, exp, iat, and the authentication-context claims auth_time, acr, amr, sid when present):
aud
: The Delegate. Unlike base OAT, where the audience is a peer Target Relying Party, here the audience is the party that will redeem the token.
azp
: The Initiator that minted the token (the Requesting Client of Exchange B). This records the minting party.
cnf
: A key the Delegate controls, not the Initiator. This is the second difference from base OAT, which binds the token to the Requesting Client's own key. See §4.2.
may_redeem
: OPTIONAL. Downstream request constraints (see §4.3).
4.2 Key Binding
Base OAT binds the token to the Requesting Client's DPoP key, because in OAT the Requesting Client is also the presenter. Here the Requesting Client (Initiator) is not the presenter (Delegate). The Initiator therefore conveys the Delegate's proof-of-possession key in Exchange B (shown as req_cnf in §3.1), and the IdP sets the OAT's cnf to that key. The Delegate proves that key when redeeming (§7).
Binding to a key supplied by the Initiator is safe because redemption additionally requires the Delegate to authenticate as the OAT's audience client on the same request (§8.2). An Initiator that bound the token to an unrelated key would produce a token only that key's holder could redeem, and only if that holder could also authenticate as the audience Delegate.
4.3 Downstream Attenuation
The may_redeem claim, when present, bounds what the Delegate may request when redeeming: an audience array of permitted RAS issuers, and optionally resource, scope, and authorization_details. At redemption the IdP MUST confirm the requested values are within may_redeem in addition to being authorized by exchange-time policy. Containment MUST be fail-closed: array intersection for audience and resource, subset for scope, and type-specific containment for authorization_details — with the IdP rejecting the request when it cannot determine containment safely. A value the IdP would otherwise apply by default is subject to the same bound, and a requested_token_type restriction (if the profile defines one) is checked the same way. Absent may_redeem, the IdP's redemption policy alone bounds the request.
5. Mint Authorization
A Mint Authorization is an eligibility relationship, administered at the IdP, permitting an Initiator to mint a Delegate-Audienced OAT for a given Delegate. It is the issuance-time analogue of the CCDR. Establishing or modifying it requires an administrative principal; a client MUST NOT establish or expand it by self-assertion through registration.
5.1 Client Metadata
Two OPTIONAL, read-only metadata views expose administered Mint Authorizations, mirroring authorized_delegates / delegate_of in the Cross-Client Delegation sketch:
mint_audiences
: On an Initiator: the client_id values it may mint Delegate-Audienced OATs for.
minters
: On a Delegate: the client_id values that may mint Delegate-Audienced OATs audienced to it.
As with the CCDR, the authorization server maintains one canonical record and any exposed views derive from it.
6. Exchange B: Minting the Delegate-Audienced OAT
Exchange B is an OAT issuance (OpenID Authentication Token Protocol) with the Delegate as the audience and the Delegate's key as the confirmation key:
requested_token_type: the OAT type, urn:openid:params:token-type:authn-token.
audience: the Delegate.
req_cnf: the Delegate's JWK SHA-256 Thumbprint, so the issued OAT is bound to the Delegate.
Authentication of the Initiator as the party the ID Token was issued to. A confidential Initiator authenticates with its client credentials. A public Initiator cannot authenticate a Token Exchange request this way — PKCE only protects the earlier authorization-code exchange, and DPoP is proof-of-possession, not client authentication — so for a public Initiator the ID Token MUST be key-bound and the Initiator MUST prove possession of the ID Token's cnf key on this request. The IdP then resolves the (audience, proven key) pair to the initiating client instance. See §11.2.
The public Initiator's DPoP proof of the ID Token's cnf key binds only the endpoint (htm/htu), not the mint request body. This sketch does not define a binding of the proof to the specific subject_token, req_cnf, and requested authority, so a captured proof could in principle be spliced onto a different mint request to the same endpoint, held off only by DPoP's own replay controls. Closing that gap is an open item (§13); note that Presenter Rebinding does not apply here, because the Initiator uses its own key and no presenter transition occurs (§12.6).
The assertion's audience equals the requesting client, so the ordinary audience rule holds and nothing is relaxed.
7. Exchange E: Redeeming for a Downstream Grant
Exchange E is a base ID-JAG Token Exchange whose subject_token happens to be a Delegate-Audienced OAT:
resource, scope, authorization_details: as appropriate for the target, within may_redeem.
Client authentication of the Delegate, and a DPoP proof of the OAT's cnf key on the same request.
The OAT's audience is the Delegate and the Delegate is the requester, so base ID-JAG's audience check passes unchanged. Exchange E is therefore audience-preserving, but it is not unmodified ID-JAG: ID-JAG accepts an Identity Assertion or a refresh token as subject_token, not an OAT, so redeeming a Delegate-Audienced OAT requires ID-JAG to accept urn:openid:params:token-type:authn-token as a subject-token type — a subject-token-type extension, distinct from and narrower than the audience-check exception the CCDR approach needs, but an ID-JAG change nonetheless. Beyond that acceptance, the mechanism as a whole adds: redeeming an OAT at Token Exchange (base OAT defines only presentation to a verifier), third-party confirmation-key selection at the mint (req_cnf), the Mint Authorization relationship, may_redeem containment, and actor-chain construction from the mint transaction. Its defining property is preserving the audience invariant, not being a single-capability delta.
8. Processing Rules
8.1 Mint (Exchange B)
Validate the subject_token (ID Token) signature, issuer, and temporal validity. The authenticated Initiator's client_id MUST be a member of the ID Token's aud; azp never substitutes for that audience check. If azp is present, this profile additionally requires it to equal the Initiator's client_id. Authenticate the Initiator per §6: a confidential Initiator by client credentials; a public Initiator by a key-bound ID Token plus proof of its cnf key on this request, resolving the (audience, proven key) pair to the initiating client instance. Reject a public-Initiator request that carries a bearer ID Token. The DPoP proof binds only the endpoint, not the mint request body; a request-body binding is an open item (§13).
Determine the requested audience; it MUST resolve to exactly one registered Delegate.
Verify a Mint Authorization permits the Initiator to mint for that Delegate, and that both registrations are enabled.
Evaluate exchange-time policy over (End-User, Initiator, Delegate).
Bind the OAT's cnf to the req_cnf key. Set azp to the Initiator, aud to the Delegate, and any may_redeem derived from policy.
Issue the Delegate-Audienced OAT.
8.2 Redemption (Exchange E)
Validate the Delegate-Audienced OAT signature, issuer (the IdP itself), and temporal validity.
Confirm the authenticated client is the OAT's aud; that is, the Delegate is redeeming its own token. Reject otherwise.
Verify the Delegate's DPoP proof against the OAT's cnf key.
Confirm the requested audience, resource, scope, and authorization_details are within may_redeem (when present) and authorized by exchange-time policy.
Resolve the Delegate's client identifier and subject at the target RAS per base ID-JAG.
Issue the ID-JAG with act identifying the Delegate, optionally nesting the Initiator per §9.
If any step fails, the IdP returns an appropriate OAuth or Token Exchange error, using error responses that do not reveal the Mint Authorization graph.
9. Issued Token Content
The downstream ID-JAG carries the Delegate as the current actor:
The IdP, not the Initiator, mints the intermediate, in response to the Initiator's request. When the IdP authenticated the Initiator's participation in that mint — client authentication for a confidential Initiator, or the key-bound-ID-Token proof of §11.2 for a public one — the mint is an authenticated act rather than a bearer forwarding, and the IdP MAY record the Initiator as a nested prior actor. Absent that authenticated participation, the IdP MUST NOT nest the Initiator:
As in RFC 8693, nested prior actors are informational and MUST NOT be used by token consumers for access control. Actor construction SHOULD align with the OAuth Actor Profile for Delegation.
10. Comparison with Cross-Client Delegation
This table compares the two cross-client approaches only. The three-way comparison that also includes modeling the gateway as a plain ID-JAG target is in the gist README; the two below are the options when the gateway cannot or should not be an ID-JAG target.
Dimension
Cross-Client Delegation (CCDR)
OAT-in-Reverse
Who presents the Initiator's assertion
the Delegate (a different client)
the Initiator itself
Audience check
relaxed under CCDR
preserved everywhere
ID-JAG change needed
an audience-check exception
a subject-token-type extension (accept the OAT as subject_token)
Authenticated handoff
separate mechanism
intrinsic for confidential Initiators; for public ones, requires the key-bound-ID-Token mint of §11.2
Captured-assertion risk
raised by the relaxation
moved to a controllable mint; for a public Initiator, closed only by key-binding the ID Token
Key binding
needs presenter transition
native (Delegate's key bound at mint)
Extra round trip
none
one
Who drives
Delegate (Broker)
Initiator (agent)
Relationship gate
CCDR (Delegate delegate-of Initiator)
Mint Authorization (Initiator may mint for Delegate)
Claims disclosed to the Delegate
the Initiator's full Identity Assertion
a purpose-minimized Delegate-audienced assertion
The two are duals: a Delegate-driven, audience-relaxing approach and an Initiator-driven, audience-preserving approach. Neither is an unmodified-ID-JAG path; they need different ID-JAG changes. A deployment can choose by topology.
11. Security Considerations
11.1 No Audience Relaxation
Neither exchange relaxes the audience rule: in Exchange B the assertion's audience is the requesting Initiator, and in Exchange E it is the requesting Delegate. The base ID-JAG audience check therefore stands unchanged, and the confused-deputy exposure that a relaxation introduces does not arise. This is the mechanism's central property.
11.2 Public-Client Mint (the crux)
The mint (Exchange B) is where captured-assertion risk concentrates, and it is the crux of #114. If the Initiator is a public client presenting a bearer ID Token, an attacker holding the captured ID Token and the public client_id could attempt Exchange B and mint a Delegate-Audienced OAT — but only bound to a key the attacker names, and redeemable only by a party that can also authenticate as the audience Delegate. The exposure is that such an attacker could mint an OAT for a colluding or attacker-controlled Delegate that it can authenticate as.
Mitigations, in increasing strength:
The mint is an IdP operation that can be rate-limited, logged, and policy-gated per (Initiator, Delegate) pair, unlike a silent presentation of a captured token.
A Mint Authorization scopes which Delegates an Initiator may mint for, so a captured ID Token cannot be minted toward an arbitrary Delegate.
Key-binding the ID Token (OpenID Connect Key Binding) or requiring the Initiator's DPoP instance key on Exchange B makes a captured bearer ID Token useless: the attacker cannot perform Exchange B without the Initiator's key. Unlike the CCDR approach, this requires no presenter-transition machinery, because the Initiator holds and proves its own key.
PKCE and DPoP do not close this gap on their own. PKCE protects only the authorization-code exchange, and DPoP proves possession of a request key without authenticating the client. For a public Initiator, therefore, the ID Token MUST be key-bound and the Initiator MUST prove possession of the ID Token's cnf key on Exchange B (§8.1); this is the grant-presentation rule that establishes the requester as the ID Token's authorized presenter. That proof binds only the endpoint (DPoP htm/htu); this sketch does not define a binding to the mint request body, so a captured proof could be spliced onto a request minting a different Delegate-Audienced OAT — an open item (§13) rather than a solved property. A public-Initiator deployment that omits the key binding inherits the full bearer-capture risk of #114 and MUST NOT claim captured-assertion resistance; even with it, the residual request-splicing exposure above remains until a request binding is defined. A confidential Initiator authenticates with its client credentials and does not depend on these rules.
Deployments with public Initiators MUST key-bind ID Tokens per the preceding paragraph and SHOULD constrain Mint Authorizations narrowly.
11.3 Mint Authorization Trust Anchor
The Mint Authorization is an eligibility input whose correctness depends on IdP administration discipline. Deployments SHOULD restrict its establishment to administrative principals, scope it narrowly, support prompt revocation, and audit changes, as for a CCDR.
11.4 Key Binding of the Intermediate
The Delegate-Audienced OAT is bound to the Delegate's key and useless to any other holder. A copy captured in transit between Initiator and Delegate cannot be redeemed without the Delegate's key and the Delegate's client authentication. This is stronger than a bearer intermediate and is why the intermediate is always key-bound.
11.5 Replay and Freshness
Both exchanges are at the IdP, which evaluates policy and status at each mint. The Delegate-Audienced OAT SHOULD be short-lived; the mechanism is otherwise online at issuance and offline between Initiator and Delegate, so revocation of a minted OAT relies on short exp unless the deployment adds a lookup. The DPoP proofs on both exchanges provide request-level replay protection.
11.6 Consent Semantics
Neither the Mint Authorization nor the mechanics establish that the End-User understood or approved disclosure to the Delegate. Deployments MUST have an applicable consent, enterprise-policy, or other authorization basis and SHOULD reflect delegation in user experience where appropriate.
11.7 Correlation and Privacy
Minting a Delegate-audienced token can correlate a user across the Initiator and Delegate audiences. The IdP SHOULD apply the Delegate audience's subject-identifier policy rather than copying an Initiator-scoped identifier. The Mint Authorization graph SHOULD NOT be publicly discoverable, and error responses SHOULD NOT enumerate it.
11.8 Cross-Organizational Delegates
Minting for a Delegate administered by another organization requires trustworthy onboarding, identifier namespacing, and key validation, and is out of scope here.
12. Composition with Related Work
12.1 OpenID Authentication Token
The intermediate is an OAT with two profile differences: the audience is the redeeming Delegate rather than a peer Relying Party, and the confirmation key is the Delegate's rather than the Requesting Client's. The capability OAT itself would need to add is redemption at Token Exchange; base OAT defines only presentation to a verifier, and states that an OAT MUST NOT be used as an access token — redemption for an ID-JAG is a Token Exchange input, not access-token use, but is nonetheless an extension OAT would need to permit. This is the OAT-side change; the ID-JAG-side change (accepting the OAT as a subject_token) is separate, and the mechanism's full surface is listed in §7.
12.2 ID-JAG
Exchange E preserves base ID-JAG's audience check — the Delegate is the audience of the OAT it presents — so it needs no audience-check exception, the dependency that blocks the Cross-Client Delegation ID-JAG composition. It is not, however, unmodified ID-JAG. ID-JAG defines its accepted subject_token types as an Identity Assertion or a refresh token; accepting a Delegate-Audienced OAT (urn:openid:params:token-type:authn-token) as a subject_token is a subject-token-type extension ID-JAG would have to define. That extension is narrower and arguably more tractable than an audience-check exception — it does not touch the audience invariant — but it is still an ID-JAG change, and this document should not be read as needing no ID-JAG coordination.
12.3 Cross-Client Delegation
The two are duals for the same problem; see §10. They can coexist, chosen by topology.
Key-binding the source ID Token (OpenID Connect Key Binding) hardens the mint against captured bearer tokens; DPoP provides the proof of possession on both exchanges and the confirmation binding of the intermediate and the issued ID-JAG.
12.6 Presenter Rebinding (why it is not needed here)
The Presenter Rebinding mechanism exists to continue proof of possession across a single change of presenter — precisely the problem the CCDR approach faces when the Delegate presents an assertion bound to the Initiator's key. OAT-in-reverse avoids that problem: the Initiator uses only its own key, and the intermediate is minted bound to the Delegate's key, so there is no cross-party key transition to perform. Note this cuts both ways — because there is no rebinding assertion, OAT-in-reverse also has no sth/cnf binding of the proof to the exact request, which is why the public-mint request binding is left open (§13).
13. Open Questions
Intermediate token type. Reuse OAT (extended to permit redemption) or define a purpose-built delegation grant? Reuse keeps the surface minimal but requires an OAT profile that permits redemption and Delegate-key binding.
Conveying the Delegate's key. How does the Initiator obtain the Delegate's cnf key — from the Delegate's invocation response, from registration, or from a nonce exchange — and how is that binding attested?
Public-client mint hardening.§11.2 requires a key-bound ID Token and a proof of its cnf key for a public Initiator; the open questions are which proof a profile should mandate — an OpenID Connect Key Binding confirmation or an Initiator DPoP instance key — and, since that proof binds only the endpoint, how to bind it to the mint request body (the subject_token, req_cnf, and requested authority) so a captured proof cannot be spliced onto a different mint. Unlike the CCDR key-bound case, there is no Presenter Rebinding assertion here to carry that binding, so this needs a mechanism of its own or an explicit accepted-risk statement.
Mint Authorization representation and discovery. Is the metadata in §5.1 sufficient, or is a protected query needed?
Latency. Is the extra round trip acceptable for high-throughput agents, or should the mint be cached or batched?
Coexistence. Should a single deployment offer both this mechanism and Cross-Client Delegation, and how does a client discover which applies?
client metadata mint_audiences and minters (§5.1); and
a means to convey a requested confirmation key at Token Exchange (shown as req_cnf in §3.1), which is not yet standardized and is tracked as an open question (§13).
It reuses the OAT token type urn:openid:params:token-type:authn-token and the ID-JAG token type urn:ietf:params:oauth:token-type:id-jag without new registration; permitting an OAT to be redeemed at Token Exchange is a profile matter for OAT rather than an IANA action.
The OAT move is defined by G. Fletcher's OpenID Authentication Token Protocol. This sketch inverts its direction — the Initiator mints for the Delegate rather than a Relying Party minting for a peer — to keep the gateway exchange audience-preserving, and is offered as a dual to the Cross-Client Delegation sketch.
Presenter Rebinding for OAuth 2.0 Proof-of-Possession Tokens (Sketch)
The building block that lets a key-bound token cross one presenter boundary without moving a private key. It is the presenter transition the Cross-Client Delegation profile composes with when the Identity Assertion is key-bound. A full Internet-Draft exists: Presenter Rebinding.
Abstract
A proof-of-possession (PoP) token ordinarily presents only when the presenter holds its confirmation key. That prevents an authorized handoff whenever transferring the private key is unacceptable. This sketch describes a deliberately one-hop mechanism for OAuth 2.0 Token Exchange: the holder of a token's confirmation key (the Original Presenter) signs a Presenter Rebinding Assertion (PRA) authorizing one Recipient Presenter key to present that exact token at one named authorization server. The Recipient presents the token and the PRA with a DPoP proof of its own key; the authorization server validates the three artifacts together. The base mechanism issues a DPoP-bound access token — and no refresh token. A consuming profile can define a different output token only if it specifies both how the Recipient key is represented in that token and how the downstream verifier checks possession. Rebinding is a single key-to-key transition, not a delegation chain.
1. Model
Rebinding continues proof of possession across exactly one change of presenter. The Original Presenter, who holds the Source Token's confirmation key, signs a PRA that names the Recipient's key and the one authorization server where it may be used. The Recipient then makes an ordinary Token Exchange, presenting the Source Token as subject_token, the PRA, and a DPoP proof of the Recipient key.
It is deliberately one hop. If the Recipient later needs to authorize a further presenter, it first obtains a new token bound to its own key and signs a new PRA for that token — each transition is a fresh exchange the authorization server decides. There is no chain, no nesting, and no onward attenuation to track. Direct presentation is unchanged: a party that already holds the Source Token's confirmation key presents the token under its own profile and never uses a PRA. Rebinding is opt-in — an authorization server accepts a PRA only under a consuming profile and policy that permit it for the Source Token type and context.
One presenter transition, not necessarily one use. Rebinding authorizes one change of presenter. Under the base mechanism it yields a DPoP-bound access token with no refresh token (§4); a consuming profile can define another sender-constrained output as described above. “One hop” does not mean one Token Exchange or one protected-resource call: unless the consuming profile requires jti replay tracking, the Recipient can submit the PRA again until it expires, and an issued token can be used according to its own lifetime and authorization semantics. The absence of a refresh token limits renewal; it does not make the output token single-use. Long-running or multi-hop work therefore needs a separately authorized continuation mechanism, such as an async-delegation profile or the Identity Continuation Assertion.
2. Terminology
Source Token
: The JWT presented as subject_token, carrying an RFC 7800cnf claim, whose presenter is being rebound (for example a key-bound ID Token).
Source Confirmation Key
: The asymmetric key identified by the Source Token's cnf. Held by the Original Presenter.
Original Presenter
: The party that holds the Source Confirmation Key and signs the PRA.
Recipient Presenter
: The party controlling the key named by the PRA's cnf, which submits the exchange and proves possession with DPoP.
Presenter Rebinding Assertion (PRA)
: A signed JWT by which the Original Presenter authorizes one Recipient Presenter key to present one exact Source Token at one authorization server.
Presenter Limits
: Optional upper bounds a PRA places on the Token Exchange — a presenter_limits object whose only defined member is audience.
3. The Presenter Rebinding Assertion
3.1 JOSE header
typ: exactly pra+jwt.
alg: an asymmetric digital-signature algorithm.
jwk: the public Source Confirmation Key, as an asymmetric JWK. The verifier confirms this key is the one the Source Token's cnf reduces to, and verifies the PRA signature under it.
3.2 Claims
Required:
sth: base64url SHA-256 digest over the ASCII octets of the exact encoded Source Token (as received, before form encoding). Binds the PRA to one specific token.
stt: the Source Token type — the subject_token_type value — so a PRA for one token type cannot be reused for another.
cnf: an object with the single member jkt, the JWK SHA-256 Thumbprint (RFC 7638) of the Recipient Presenter's DPoP key.
aud: the authorization server's issuer identifier, as a single case-sensitive string (not an array).
iat, exp: issuance and a short expiry.
Optional:
jti: an identifier for audit, replay tracking, or revocation. A consuming profile that promises single-use PRA semantics MUST require jti and require the authorization server to reject reuse.
presenter_limits: an object whose only defined member is audience, an array bounding the Token Exchange audience the Recipient may request. There is intentionally no resource, scope, or authorization_details dimension. The PRA therefore supplies no attenuation in those dimensions; the consuming profile and exchange-time policy MUST prevent authority escalation and decide any narrowing. A deployment that needs the Original Presenter itself to authorize a narrower resource, scope, or authorization detail needs a richer mechanism.
The Recipient makes a Token Exchange carrying the Source Token as subject_token, the PRA in the presenter_rebinding parameter (its compact JWS), and a DPoP proof of the Recipient key. The authorization server, as verifier:
validates the Source Token per its own type and profile, and reduces its cnf to a single JWK SHA-256 Thumbprint;
validates the PRA: typ is pra+jwt; jwk is the Source Confirmation Key (its thumbprint equals the Source Token's); the signature verifies under it; sth equals the digest of the exact Source Token presented; stt equals the subject_token_type; aud is this authorization server's issuer; iat/exp are within policy; cnf.jkt is present;
when the consuming profile requires single-use, requires jti and atomically rejects a previously consumed value;
verifies the DPoP proof and confirms its key thumbprint equals the PRA's cnf.jkt;
confirms the requested audience lies within presenter_limits.audience when present, and is independently authorized by the consuming profile and exchange-time policy;
on success, issues an access token sender-constrained to the Recipient key. A consuming profile MAY instead define another output token type only when it defines how that token represents the Recipient-key binding and how its verifier checks possession; §7 defines the ID-JAG specialization used by Cross-Client Delegation. The authorization server MUST NOT issue a refresh token (Section 6.2 of the draft): continuation requires a separately authorized mechanism.
5. Design invariants
The base mechanism is fixed on purpose — one assertion type, one confirmation method, one output (a DPoP-bound access token), one narrowing dimension (audience), and exactly one hop. A consuming profile that defines another output must supply the key-binding and verifier rules required by §4; otherwise, widening any of these overrides a normative requirement and updates this document rather than extending it. One hop is a security boundary, not a simplification: requiring each transition to be its own exchange means the authorization server decides, every time, who may present what.
A key thumbprint is not an identity. Possession of the Recipient key, the PRA signature, and the Source Token together establish that a particular key was authorized to present a particular token — not who controls that key or what OAuth relationship exists. Consuming profiles apply their own client or actor authentication on top.
6. Binding, and why there is no request hash
The presentation is bound by the conjunction of four checks on one TLS-protected request: the PRA aud names this authorization server; the DPoP htm/htu bind the proof to this endpoint and method; sth binds to the exact Source Token; and cnf.jkt ties the PRA to the key the Recipient proves. There is deliberately no claim that hashes the full Token Exchange request body. Binding rests on the assertion (sth + aud + cnf.jkt) plus DPoP's endpoint binding and the verifier evaluating the Source Token, the PRA, and the proof from the same request — which is what the one-hop, fixed-shape design trades for a general request-binding claim. A deployment that needs the requested audience itself constrained uses presenter_limits.audience.
7. Use in delegation profiles
A consuming profile names its verifier (authorization server) audience identifier, states that the Source Token is a key-bound assertion whose cnf reduces to the Original Presenter's key, defines how the Original Presenter obtains and authenticates the Recipient key, and maps its request to the PRA. A PRA proves authorization by the Source Confirmation Key; it does not, by itself, identify either presenter.
The Cross-Client Delegation profile composes with rebinding for the key-bound case: the Initiator is the Original Presenter, the Delegate is the Recipient Presenter, and the IdP additionally authenticates the Delegate and maps the Source Confirmation Key to the Initiator. Its ID-JAG specialization has the following output rules:
the exchange requests urn:ietf:params:oauth:token-type:id-jag as its requested_token_type;
the response carries the ID-JAG in access_token, with issued_token_type set to urn:ietf:params:oauth:token-type:id-jag and token_type set to N_A, as required by ID-JAG;
the issued ID-JAG contains cnf.jkt equal to the PRA Recipient key thumbprint;
the Resource Authorization Server verifies a DPoP proof for that key when the ID-JAG is redeemed; and
the IdP does not issue a refresh token.
These rules make this section the applicable non-access-token output profile required by Presenter Rebinding. A valid PRA, together with the independent Initiator-key mapping and Delegate authentication, is authenticated per-assertion evidence that the Initiator authorized this exact handoff; Cross-Client Delegation can therefore record the Initiator as a nested prior actor. Rebinding is an optional composition; the base Cross-Client profile excludes key-bound assertions rather than requiring rebinding.
8. Authorization Server Metadata
presenter_rebinding_supported: OPTIONAL boolean; the authorization server accepts a PRA under a consuming profile.
presenter_rebinding_signing_alg_values_supported: OPTIONAL array of JWS alg values accepted for PRA signatures.
9. Security and Privacy Considerations
No key leaves its holder. The Original Presenter signs with a key it holds and authorizes a public key; the Recipient proves its own key. Compromise of the Original Presenter's key lets an attacker sign PRAs that party could have signed, bounded to the exact Source Token and one authorization server; it exposes no Recipient key.
Opt-in, per profile. Possession of a confirmation key does not oblige any issuer or verifier to accept a rebinding of it; a PRA is not a signal that an unaware token profile must accept a handoff.
Replay and freshness. A captured PRA is usable only by a party that also controls the Recipient key and can produce a fresh DPoP proof; sth, aud, cnf.jkt, and a short exp bound it. DPoP replay detection prevents reuse of a DPoP proof, not authorized reuse of the PRA with newly generated proofs. Single-use PRA semantics require a mandatory jti and atomic replay state at the authorization server.
Type confusion. The pra+jwt type, the key-derived signature, and rejection of none/symmetric algorithms keep a PRA from being confused with an ID Token, access token, or DPoP proof.
No refresh token. The exchange cannot create renewable authority through a refresh token. The output token is still reusable unless its own profile says otherwise, and a reusable PRA can drive more than one exchange during its lifetime.
Correlation. The PRA discloses the Original and Recipient key thumbprints to the authorization server; the key-derived material is a stable correlation handle. A Recipient MAY use a fresh per-handoff key.
10. IANA Considerations
TBD. The draft registers: the application/pra+jwt media type; JWT claims sth, stt, and presenter_limits; the OAuth token-request parameter presenter_rebinding; and authorization-server metadata presenter_rebinding_supported and presenter_rebinding_signing_alg_values_supported. The cnf, aud, iat, exp, and jti claims are already registered and used unchanged.
Token Exchange Profile for Cross-Client Delegation (Sketch)
Abstract
This profile extends OAuth 2.0 Token Exchange (RFC 8693) to permit a
confidential client (the Delegate) to obtain a token on behalf of another
OAuth client (the Initiator) with which the IdP has an administered trust
relationship. The Delegate presents the Initiator's Identity Assertion as
subject_token, identifies itself via actor_token, and authenticates to the
IdP. The IdP validates a pre-registered Cross-Client Delegation Relationship
and issues a token that identifies the Delegate as the current actor via the
RFC 8693 act claim.
An Identity Assertion MAY additionally contain an RFC 8693 may_act claim
identifying the Delegate. When present, may_act narrows the actors eligible
to use that particular assertion and MUST match the actor established by
actor_token. In the absence of may_act, the administered relationship and
fresh IdP policy determine eligibility.
This addresses the same cross-client topology as OpenID Connect cross-client
identity (Google's cross-client identity) and the ID-JAG Broker
deployment (ID-JAG Enterprise Broker Deployment Pattern), but with a distinct Token Exchange mechanism.
Cross-client identity changes issuance so the Delegate is an audience; this
profile instead authorizes a narrowly scoped exception when it is not.
1. Introduction
Modern OAuth deployments increasingly encounter topologies where the OAuth
client that authenticates the user (the Initiator) is not the OAuth client
that will present the resulting token to a downstream resource (the
Delegate). Enterprise agent-plus-gateway topologies, mobile-app-plus-BFF
patterns, and MCP gateway deployments all share this shape.
OAuth 2.0 (RFC 6749) and Token Exchange (RFC 8693) do not define how an
authorization server administers an eligibility relationship between two
OAuth client registrations. Deployments today rely on:
ad-hoc administrative configuration invisible to protocol readers; or
non-standard Token Exchange conventions.
This profile defines a Token Exchange path for cross-client delegation using:
client authentication to identify the requester;
RFC 8693 actor_token to establish the acting party;
an administered relationship as an authorization-server-side eligibility
rule;
optional RFC 8693 may_act as a per-assertion constraint; and
RFC 8693 act to identify the actor accepted into the issued token.
The administered relationship and may_act have related but distinct
functions. The relationship states that a client pairing is eligible under
IdP policy. A may_act claim, when present, restricts which actor may use a
particular subject token. Neither mechanism by itself proves that the
Initiator actively conveyed a particular assertion to the Delegate.
1.1 Applicability and Non-Goals
This profile applies wherever an OAuth 2.0 Token Exchange request is made by
a confidential client acting on behalf of another OAuth client with which the
IdP has an administered trust relationship. It composes with token-specific
profiles such as ID-JAG, which may impose additional constraints on the
requested token type, audience, or claims.
For the agent→gateway case, this profile is the fallback, not the first
choice: when the gateway can be a registered client and obtain its own
assertion, the cleaner answer is to issue the user's assertion audienced to
the gateway and use base ID-JAG, per the
Agent-to-Gateway Handoff recommendation. This
profile is for when that issuance is not available — a third-party or
unregistered gateway the IdP will not issue user identity for.
Explicit non-goals of this profile:
CCDR enrollment protocol. How a Cross-Client Delegation Relationship is
established at the authorization server is a deployment concern.
Cross-organizational trust establishment. Recognition of a Delegate
administered by a different organization is out of scope; see §11.7.
Authenticated handoff. A mechanism proving that the Initiator actively
conveyed a particular Identity Assertion to the Delegate is out of scope for
the base profile; see §11.3. A
deployment that needs an authenticated, per-assertion handoff composes with
Presenter Rebinding
(§12.5) for the key-bound case,
which the base profile otherwise excludes (§8).
End-User consent UX. How delegation is surfaced to the End-User (if at
all) is a deployment concern subject to applicable policy.
Public discovery of the CCDR graph. This profile does not require
that CCDRs be discoverable by other clients.
2. Terminology
Initiator
: The OAuth client that authenticated the End-User and holds an Identity
Assertion (typically an ID Token) whose audience is the Initiator's
client_id.
Delegate
: A confidential OAuth client authorized to present the Initiator's Identity
Assertion to Token Exchange in order to obtain a token on the End-User's
behalf.
Cross-Client Delegation Relationship (CCDR)
: An authorization-server-administered eligibility relationship between an
Initiator and one or more Delegates, described in §4.
Per-Assertion Actor Authorization
: An optional authorization expressed by an RFC 8693 may_act claim in an
Identity Assertion. It identifies an actor eligible to act on behalf of the
subject of that assertion. It narrows, and does not expand, the actors
permitted by the CCDR and current IdP policy.
Identity Assertion
: A security token issued by an authorization server that conveys claims
about the End-User and is suitable for use as subject_token in Token
Exchange. Typically an OpenID Connect ID Token (OpenID Connect Core) or a SAML
2.0 assertion.
The End-User authenticates the Initiator at the IdP normally. The
Initiator holds an Identity Assertion with aud = Initiator.client_id.
The assertion MAY contain a may_act claim identifying a Delegate that
is eligible to act on behalf of its subject.
The Initiator conveys the Identity Assertion to the Delegate. This profile
does not define the transport and does not treat the mere audience value
as cryptographic proof of this handoff.
The Delegate performs Token Exchange at the IdP:
subject_token: the Identity Assertion;
actor_token: a credential establishing the Delegate as the actor; and
client authentication: authentication of the Token Exchange requester as
the Delegate.
The IdP validates the Cross-Client Delegation Relationship between the
Initiator and the Delegate.
If the Identity Assertion contains may_act, the IdP verifies that it
identifies the same Delegate established by actor_token. A mismatch is
fatal; the CCDR MUST NOT override or broaden may_act.
The IdP evaluates fresh policy over (User, Initiator, Delegate, requested audience, resource, scope, authorization_details).
The IdP issues the requested token with an act claim identifying the
Delegate as the current actor.
3.1 Example
A minimal illustration of the input assertion, the Token Exchange request, and
the issued token. Values are abbreviated for readability.
authorized_delegates
: OPTIONAL. A JSON array of client_id values eligible to act as Delegates
for this client.
For Delegates
delegate_of
: OPTIONAL. A JSON array of client_id values for Initiators on whose behalf
this client is eligible to act.
These values are authorization-server-administered policy views. A client
MUST NOT be permitted to establish or expand a CCDR merely by submitting one
of these values through dynamic registration or registration management.
Establishing or modifying a CCDR requires authorization by an administrative
principal at the IdP. This profile does not define the enrollment protocol
or user interface for CCDR management; that is a deployment concern.
The authorization server MUST maintain one canonical relationship record.
If both metadata views are exposed, they MUST be derived from that record and
MUST be mutually consistent.
The relationship MAY be maintained purely in IdP-side configuration. This
profile does not define public discovery of the relationship graph.
5. Token Exchange Request
A Token Exchange request under this profile includes:
grant_type:
urn:ietf:params:oauth:grant-type:token-exchange, per RFC 8693;
subject_token: the Initiator's Identity Assertion;
subject_token_type: as appropriate for the Identity Assertion type;
actor_token: REQUIRED, identifying the Delegate as described in
§6;
actor_token_type: REQUIRED and appropriate for the actor credential;
client authentication: the Delegate authenticates the Token Exchange
request using a method accepted by the IdP for confidential clients; and
other Token Exchange parameters (audience, resource, scope,
authorization_details, and requested_token_type) as appropriate for the
requested downstream token.
The authenticated client and the actor are distinct protocol concepts. This
profile requires them to identify the same Delegate.
6. Actor Token
6.1 Requirements
For this profile, actor_token is a security token that establishes the
Delegate as the acting party. The actor token MUST:
identify the Delegate's client_id (typically via sub);
be verifiable by the IdP under its native token-type validation rules;
include replay protection appropriate to its token type (e.g. jti plus
iat/exp for JWTs); and
resolve to the same client_id as the client authenticated for the Token
Exchange request.
actor_token MUST NOT be an access token. Access tokens are resource
authorization credentials, not identity artifacts for the acting party;
using one as actor_token conflates the two functions. This restriction
aligns with the function-based subject_token selection defined by ID-JAG.
Companion profiles MAY relax this restriction where deployment context
justifies it.
The IdP MUST confirm that the actor established by actor_token is the same
Delegate identified by client authentication. A profile that permits the
actor to differ from the authenticated OAuth client is outside the scope of
this document.
6.2 RFC 7523 JWT Profile
When actor_token is an RFC 7523 JWT client assertion:
actor_token_type is urn:ietf:params:oauth:token-type:jwt;
iss and sub identify the Delegate's client_id;
aud identifies the IdP token endpoint or other audience accepted by the
IdP under RFC 7523;
the JWT includes iat, exp, and jti;
the JWT is signed using a key registered for the Delegate; and
the IdP applies its RFC 7523 validation and replay-detection rules.
The same JWT value MAY be presented as both client_assertion and
actor_token when the IdP supports that usage. Alternatively, the Delegate
MAY authenticate using another accepted method and present a separate actor
credential.
7. Per-Assertion Actor Authorization
An Identity Assertion used as subject_token MAY include a may_act claim as
defined by Section 4.4 of RFC 8693.
When present, may_act:
identifies a party eligible to become the actor for the subject of the
Identity Assertion;
MUST contain sufficient issuer-scoped identity claims to identify the
Delegate, normally iss and sub;
MUST identify the same party established by actor_token; and
narrows the CCDR and current IdP policy rather than expanding them.
The IdP MUST NOT authorize a different Delegate merely because that Delegate
is eligible under the CCDR. A may_act mismatch MUST cause the exchange to
fail.
Absence of may_act does not by itself prohibit the exchange. In that case,
the IdP uses the CCDR and fresh policy to decide whether the authenticated
Delegate may become the actor.
A may_act claim issued by the IdP represents authorization by the IdP for
the named actor to act on behalf of the assertion subject. It does not prove
that the Initiator subsequently participated in, or authorized, a particular
handoff of the assertion.
8. Token Exchange Processing
Profile selection. This profile defines no request parameter that names
itself. The IdP first validates the assertion except for the token-profile
audience check, then examines that audience against the authenticated client.
If the authenticated client's client_id is an allowed member of the
assertion audience, the applicable base token profile governs and this profile
does not. If it is not an audience, the IdP attempts the cross-client processing
below. Only successful Initiator resolution and completion of every CCDR check
authorizes replacing the audience-equals-authenticated-client check.
Because selection is by request content, the IdP MUST make dispatch
deterministic and MUST NOT allow silent downgrade:
if more than one content-selected Token Exchange profile could match a
request, the IdP MUST apply a configured, documented precedence and MUST NOT
process the request under more than one profile;
a request that matches this profile's cross-client shape (resolved Initiator
differs from the authenticated client) but fails this profile's checks MUST be
rejected, never reprocessed under the base profile or another profile; and
a key-bound (sender-constrained or proof-of-possession-bound) subject token is
out of scope for the base profile and MUST NOT be processed as a bearer
assertion (see the note after the steps).
Whether an explicit request parameter should name this profile rather than
relying on content selection is an open question (§13).
The IdP MUST apply the following processing:
Validate the subject_token signature, issuer, expiration, and every other
requirement applicable to its Identity Assertion type, except the normal
requirement that the assertion identify the authenticated requesting client
as its audience. This profile replaces that one check — and nothing else —
with Initiator resolution (step 2) and CCDR authorization (step 5). The IdP
MUST verify the assertion issuer is the IdP's own issuer identifier, and MUST
reject a token positively identifiable as a type other than the declared
subject_token_type.
Determine exactly one Initiator using the IdP's issuer-scoped
client-registration mapping. For an ID Token with one aud value, that value
identifies the Initiator; if azp is present, it MUST identify the same
client. For a multi-valued aud, this profile requires azp, requires the
azp value to be one of the audiences, and uses it as the Initiator. If
these conditions do not hold, the IdP MUST reject the cross-client request.
The selected identifier MUST resolve to exactly one client registration.
These are profile constraints for unambiguous dispatch: OpenID Connect still
requires a client to occur in aud, while azp is an additional
authorized-party check and never substitutes for audience membership.
Validate actor_token according to its token type and determine the actor
identity.
Confirm that the actor identity matches the client authenticated for the
request (the Delegate).
Verify that the Initiator and Delegate registrations are currently enabled
and that a CCDR currently authorizes the Delegate to act for the Initiator.
The IdP MUST NOT treat a prior actor recorded in a nested act chain within
the subject token as an authorization input: per Section 4.1 of RFC 8693
such prior actors are informational. An IdP MAY apply local policy to
ancestor status as an additional, optional signal, but MUST NOT make it a
required part of this authorization decision. See §11.9.
If the subject token contains may_act, verify that may_act identifies
the same Delegate. The IdP MUST NOT ignore a mismatch or use the CCDR to
broaden the assertion's per-token authorization.
Evaluate policy over (End-User, Initiator, Delegate, requested audience, resource, scope, authorization_details) according to IdP configuration.
On success, issue the requested token according to §9.
Key-bound subject tokens are out of base scope. The base profile accepts
only a non-key-bound Identity Assertion. An ID Token that is sender-constrained
or proof-of-possession-bound (for example bound to the Initiator's key via
OpenID Connect Key Binding) MUST NOT be accepted here, because the Delegate does
not hold the Initiator's key and so cannot demonstrate proof of possession. A
deployment that needs the key-bound case composes this profile with
Presenter Rebinding
(§12.5): the Initiator signs a
one-hop assertion authorizing the Delegate's key to present that exact token.
That composition is OPTIONAL; the base profile neither requires nor defines it,
and there is no bearer "downgrade" of a key-bound assertion.
If any step fails, the IdP MUST return an appropriate OAuth or Token Exchange
error. Actor-token validation or may_act/CCDR authorization failures SHOULD
use an error response that does not reveal the IdP's relationship graph.
9. Issued Token Content
When the requested token is a JWT capable of carrying RFC 8693 claims, the
issued token includes:
sub: an identifier for the End-User appropriate to the issued token's
audience;
aud: the audience determined for the requested token;
client_id: the client identifier required by the issued token's profile;
and
act: an actor claim per Section 4.1 of RFC 8693 identifying the
Delegate as the current actor:
The outer act.sub MUST NOT be omitted merely because it duplicates a
client_id claim. The two claims have distinct semantics.
The Initiator MUST NOT be added as a nested prior actor solely because its
client identifier was the audience of the input Identity Assertion or
because a may_act claim was present. A nested Initiator MAY be included only
when an additional mechanism establishes that the Initiator actively
participated in the delegation of that particular assertion:
As required by RFC 8693, nested prior actors are informational and MUST NOT be
used by token consumers for access-control decisions.
Other claims are included according to the requested token type and
applicable token profile.
10. Discovery / Metadata
Authorization Server Metadata
This profile is selected by request content (§8),
not by a request parameter. It uses dedicated IdP Authorization Server metadata
because this capability concerns processing at the IdP's Token Exchange
endpoint. ID-JAG's authorization_grant_profiles_supported describes profiles
processed by a Resource Authorization Server and is therefore not reused here.
cross_client_delegation_supported
: OPTIONAL boolean. When true, the IdP accepts Token Exchange requests under
this profile.
cross_client_delegation_token_types_supported
: OPTIONAL. A JSON array of objects describing the
(subject_token_type, actor_token_type) combinations the IdP will accept
under this profile. Each object has a subject_token_type URI and an
actor_token_type URI.
These metadata values indicate what the IdP implements. They do not disclose any
particular CCDR and do not guarantee that a particular Initiator, Delegate,
subject token, actor token, audience, resource, scope, or authorization request
will be accepted for a given exchange.
Agent-to-Gateway Discovery
Agent-facing discovery (how an Agent learns which token kind to send to a
Gateway) is out of scope for this profile. It is a Gateway-side or
application-layer metadata concern with different actors and different
discovery surfaces from authorization server metadata.
11. Security Considerations
11.1 Trust Anchor for the Relationship
The CCDR is an eligibility input to authorization policy. Its correctness
depends on the IdP's administration discipline. Deployments SHOULD:
restrict the ability to establish a CCDR to administrative principals;
scope relationships as narrowly as possible;
support prompt revocation; and
audit relationship changes.
11.2 Relationship Between CCDR and may_act
The CCDR and may_act are conjunctive when both are present. A CCDR MUST NOT
override a may_act claim that identifies a different actor.
The presence of may_act does not eliminate the need for exchange-time
policy. The claim describes an eligible actor for the assertion subject; it
does not grant arbitrary audience, resource, scope, or
authorization_details values.
11.3 Captured Identity Assertion Value
In the absence of a cryptographically authenticated handoff, any Delegate
eligible under the CCDR might be able to use a captured bearer Identity
Assertion. A may_act claim limits which Delegate can exploit such a captured
assertion but does not prove that the Initiator conveyed it.
Deployments SHOULD use short assertion lifetimes and replay detection. The base
profile has no cryptographically authenticated handoff and therefore accepts
only non-key-bound assertions. A deployment that needs an authenticated,
per-assertion handoff composes with Presenter Rebinding
(§12.5): the Initiator signs a
one-hop assertion authorizing the Delegate's key to present that exact token, so
the Delegate proves an Initiator-authorized presentation rather than forwarding
a bearer assertion. An assertion bound only to the Initiator's key cannot be
presented by the Delegate without that composition.
11.4 Delegate Compromise
Compromise of a Delegate's credentials may permit obtaining tokens for every
Initiator linked to that Delegate. Relationships SHOULD be narrowly scoped,
and Delegate credentials SHOULD be rotated with the discipline applied to
sensitive service credentials.
Where Identity Assertions include may_act, compromise impact is limited to
assertions that name the compromised Delegate, but existing assertions remain
usable until they expire, are revoked, or are rejected by current IdP policy.
11.5 Freshness
The IdP MUST evaluate policy at exchange time. The CCDR and may_act
establish eligibility, not entitlement to any specific exchange. Audience,
resource, scope, and authorization_details remain subject to policy.
Freshness applies to the parties this profile authorizes. The IdP MUST
re-check, at each mint, that the Initiator and the Delegate registrations are
enabled and the CCDR still authorizes the pair. A prior actor recorded only in
a nested act chain is not an authorization input (see
§8 step 5 and §11.9),
so it is not part of this re-check.
11.6 Transport of Identity Assertion
This profile does not define how the Initiator conveys the Identity Assertion
to the Delegate. Transport SHOULD provide confidentiality, integrity, and
session correlation.
Deployments requiring proof that the Initiator actively authorized a
particular handoff need an additional Initiator-authenticated mechanism. Such
a mechanism MAY allow the IdP to record the Initiator as a nested prior actor.
11.7 Cross-Vendor Interoperability
The CCDR is administered by the IdP that validates the Identity Assertion.
Cross-vendor gateway deployments require the IdP to recognize the Delegate
and its actor credential. This profile does not define how trust is
established across organizations.
11.8 Consent Semantics
Neither a CCDR nor may_act by itself establishes that the End-User
understood or approved disclosure to the Delegate. Deployments MUST have an
applicable consent, enterprise-policy, or other authorization basis and
SHOULD reflect delegation in user experience where appropriate.
11.9 Revocation Propagation
Revocation of the Initiator or the Delegate propagates through the mint-time
check required by §8 (step 5): the IdP verifies
both registrations are currently enabled and the CCDR currently authorizes the
pair. A token already issued cannot be revoked retroactively based on
subsequent status changes; deployments SHOULD use short exp values on issued
tokens to bound the residual window.
This profile does not provide a revocable multi-party authorization chain.
The act claim it issues is an audit record of the accepted actor context, not
an authorization input (see §9 and Section 4.1 of RFC 8693),
so revoking a party that appears only as a nested prior actor does not, by
itself, invalidate a later exchange. A deployment that needs authority whose
every step can be revoked and re-checked should carry it in a structure designed
for that — for example a fresh per-hop exchange (as Presenter Rebinding requires,
being one hop) or a continuation-chain authorization envelope — rather than in
act.
The same bounded window applies to may_act. A may_act binding is
point-in-time: if the Delegate it names is later revoked, tokens already minted
using that assertion remain valid to their exp.
12. Composition with Related Work
12.1 RFC 8693 may_act
This profile uses may_act without changing its RFC 8693 semantics.
may_act is an input authorization statement identifying an eligible actor;
actor_token proves the proposed actor's identity; and act records the
actor accepted into the output token.
The CCDR is an authorization-server-side eligibility rule that can be used
when the subject token does not carry may_act. When both are present, both
must authorize the Delegate.
12.2 OpenID Connect Cross-Client Identity
Deployments MAY implement both OpenID Connect cross-client identity and this
profile. This profile keeps the base Identity Assertion audience unchanged
unless a deployment deliberately adds may_act as an extension. It does not
require an ID Token audience array.
12.3 OAuth 2.0 Identity Assertion Authorization Grant (ID-JAG)
Composing this profile with ID-JAG Token Exchange is not jointly
implementable today. This profile relaxes the audience-equals-authenticated-client
check on the input Identity Assertion, but ID-JAG does not define a hook that
lets a companion profile substitute its own check for that one. Until ID-JAG
defines such an audience-check exception point, the enterprise Broker
deployment that relies on this composition (see the
Enterprise Broker pattern) cannot be built
from the two specifications as written. This is the profile's principal
external dependency.
Where the hook exists, the composition is as follows: when the requested token
is an ID-JAG, the issued ID-JAG carries the Delegate as the current actor, and
the ID-JAG's base audience and client-binding rules continue to apply. The
Initiator is not automatically a nested actor; recording it as a prior actor
requires an additional authenticated handoff mechanism as described in
§9.
12.4 OpenID Connect Key Binding
Key-binding an Identity Assertion to the Initiator's key is deliberately outside
the base profile (§8): the Delegate does not
hold the Initiator's key and so cannot demonstrate proof of possession for such
an assertion. The base profile therefore accepts only non-key-bound assertions.
A deployment that needs both key binding and cross-client delegation uses the
optional composition in §12.5.
12.5 Composition with Presenter Rebinding
A deployment MAY compose this profile with
Presenter Rebinding to admit a key-bound
Identity Assertion. The Initiator — the Original Presenter, holding the
assertion's confirmation key — signs a one-hop Presenter Rebinding Assertion
(PRA) authorizing the Delegate's key to present that exact assertion at the IdP;
the Delegate presents the assertion, the PRA, and a DPoP proof of its own key.
This continues proof of possession across the single change of presenter without
moving a private key.
The composition requires an authenticated, integrity-protected mechanism for
the Initiator to obtain the Delegate's public key and bind it to the Delegate's
client registration. This document does not define that mechanism; a deployment
or companion profile MUST define it before this composition is interoperable.
The IdP MUST also establish that the assertion's Source Confirmation Key is the
key bound to the resolved Initiator. A PRA alone proves control and delegation
by a key; it does not identify that key holder as the Initiator.
For this composition, the request MUST set requested_token_type to
urn:ietf:params:oauth:token-type:id-jag. The IdP response MUST follow ID-JAG:
it carries the grant in access_token, sets issued_token_type to
urn:ietf:params:oauth:token-type:id-jag, and sets token_type to N_A. The
issued ID-JAG MUST contain cnf.jkt equal to the Recipient key thumbprint from
the PRA. When the ID-JAG is redeemed, the Resource Authorization Server MUST
verify a DPoP proof whose key has that thumbprint. The IdP MUST NOT issue a
refresh token. These are the non-access-token output and verifier rules required
by Presenter Rebinding; without them, its base profile issues only a DPoP access
token and cannot produce the ID-JAG needed here.
With those independent identity mappings and checks, the PRA is authenticated,
per-assertion evidence that lets the IdP record the Initiator as a nested prior
actor (§9). The composition is OPTIONAL and it is one
hop: it does not turn this profile's authorization into a standing multi-party
chain. It also remains subject to the unresolved ID-JAG audience-check hook in
§12.3. Absent
this composition, the key-bound case is out of scope here.
12.6 draft-mcguinness-oauth-actor-profile
Actor-token validation and act construction SHOULD align with the Actor
Profile for Delegation, including its rules for using an RFC 7523 client
assertion as both client authentication and an actor credential.
13. Open Questions
Per-assertion authorization. Should profiles using OIDC require
may_act, or retain the CCDR-only mode for unchanged ID Tokens?
Authenticated handoff. The optional composition with Presenter Rebinding
(§12.5) provides an
authenticated, per-assertion handoff for the key-bound case. What remains
open is whether anything strengthens the base (non-key-bound) mode short of
that, and whether a may_act claim signed by the assertion's issuer is
sufficient authorization to record the Initiator as a nested prior actor in
act, or whether the current strict requirement (Initiator-authenticated
evidence, such as a PRA) holds.
Relationship exposure. Should an authenticated client be able to query
its own CCDRs through a protected endpoint?
Actor credential types. Is an RFC 7523 client assertion sufficient for
the base profile, with workload credentials and access tokens defined by
companion profiles?
Consent surface. Under which deployment policies is administrative
authorization sufficient, and when must the delegation be shown to the
End-User?
Cross-organizational Delegates. How does the IdP recognize and
namespace a Delegate controlled by another organization?
Generic client relationships. If a broader client_relationships
primitive emerges, how should CCDR be represented within it?
Delegate key distribution. What standard mechanism lets an Initiator
authenticate the Delegate's rebinding key and bind it to the intended
Delegate registration without adding a deployment-specific control plane?
14. IANA Considerations
TBD. This profile may register:
client metadata: authorized_delegates, delegate_of; and
authorization server metadata: cross_client_delegation_supported and
cross_client_delegation_token_types_supported.
The may_act claim and the jti claim are already registered; this profile
does not request new registrations for them.