Skip to content

Instantly share code, notes, and snippets.

@mcguinness
Last active July 28, 2026 04:19
Show Gist options
  • Select an option

  • Save mcguinness/aa44d94a0ed45827985e7f3ade17852c to your computer and use it in GitHub Desktop.

Select an option

Save mcguinness/aa44d94a0ed45827985e7f3ade17852c to your computer and use it in GitHub Desktop.
Draft response to ID-JAG issue #114: Cross-Client Delegation Profile + ID-JAG Enterprise Broker Deployment Pattern

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).

This gist contains two documents:

  • Token Exchange Profile for Cross-Client Delegation — a generic mechanism sketch. Defines the Cross-Client Delegation Relationship (CCDR), actor_token handling, may_act interaction, and act claim construction at the Token Exchange layer. Factors out the shape that OpenID Connect cross-client identity, the ID-JAG Broker case, and similar patterns all implement.

  • ID-JAG Enterprise Broker Deployment Pattern — an informative deployment pattern applying the generic profile to ID-JAG. Describes the enterprise MDM + gateway topology, the authenticated handoff and correlation controls the Broker enforces, client_id namespace handling at the Resource Authorization Server, and composition with key binding and attestation.

Reading order

  1. Start with the sketch for the mechanism.
  2. Then the deployment pattern for how it lands in the enterprise gateway case.

Provenance

The enterprise deployment shape is derived from @zekth's comment on #114. The generic factor-out came out of subsequent discussion.

Status

Sketches for WG discussion. Both documents are informative markdown, not yet Internet-Drafts.

ID-JAG Enterprise Broker Deployment Pattern

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

  1. 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.
  2. 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.
  3. 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.
    • requested_token_type: urn:ietf:params:oauth:token-type:id-jag.
    • audience: the issuer identifier of the target Resource Authorization Server.
    • resource, scope, and authorization_details as appropriate for the target protected resource.
  4. 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.
  5. 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:

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

An illustrative issued ID-JAG contains:

{
  "iss": "https://idp.example",
  "sub": "<user identifier for the target trust domain>",
  "aud": "https://authorization-server.example/",
  "client_id": "broker-client-at-resource-as",
  "cnf": {
    "jkt": "<Broker key thumbprint>"
  },
  "act": {
    "iss": "https://idp.example",
    "sub": "broker-client-at-idp"
  }
}

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:

  1. The Managed Client registration is eligible to participate in the enterprise deployment and is one endpoint of the CCDR.
  2. The Broker registration is the other endpoint of the CCDR, and the Broker is authenticated on the Token Exchange request.
  3. 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 the current status of the Managed Client, the Broker, and any prior actors recorded in nested act chains at each mint per the Cross-Client Delegation profile (see Cross-Client Delegation Profile, §11.9). Ancestor revocation propagates only through this mint-time check. A token already issued cannot be revoked retroactively based on subsequent ancestor status changes; 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 chain revocation propagation. Mint-time ancestor status checks are tractable within a single IdP (this pattern). When a chain spans organizations, the check requires reaching another authority. 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 pattern is additive over base ID-JAG. It 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. Key binding requires a presenter-transition or authorized rebind mechanism from the Managed Client to the Broker. It does not require or permit transfer of the Managed Client's private key.
  • 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:

12. References

Technical requirements are inherited from the Cross-Client Delegation and base ID-JAG specifications. References for this informative pattern:

  • ID-JAG base specification.
  • RFC 7591 OAuth 2.0 Dynamic Client Registration.
  • RFC 7636 PKCE.
  • RFC 8693 OAuth 2.0 Token Exchange.
  • RFC 7523 JWT Profile for OAuth 2.0 Client Authentication and Authorization Grants.
  • Cross-Client Delegation profile sketch: token-exchange-cross-client-delegation-sketch.md.
  • ID-JAG issue #114 and referenced comment.

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 factors out the shape that OpenID Connect cross-client identity (Google's cross-client identity), the ID-JAG Broker Profile (ID-JAG Enterprise Broker Deployment Pattern), and similar patterns implement into a generic Token Exchange-layer profile.

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:

  • deployment-specific cross-client identity conventions;
  • 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.

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; see §11.3.
  • 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.

Common OAuth and Token Exchange terms are used as defined in RFC 6749, RFC 8693, and OpenID Connect Core.

3. Overview

At a high level:

  1. 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.
  2. 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.
  3. 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.
  4. The IdP validates the Cross-Client Delegation Relationship between the Initiator and the Delegate.
  5. 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.
  6. The IdP evaluates fresh policy over (User, Initiator, Delegate, requested audience, resource, scope, authorization_details).
  7. 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.

Identity Assertion presented as subject_token:

{
  "iss": "https://idp.example",
  "sub": "user-123",
  "aud": "initiator-client",
  "may_act": {
    "iss": "https://idp.example",
    "sub": "delegate-client"
  }
}

Token Exchange request from the Delegate:

POST /token
Host: idp.example
Content-Type: application/x-www-form-urlencoded

grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&subject_token=<Identity Assertion>
&subject_token_type=urn:ietf:params:oauth:token-type:id_token
&actor_token=<Delegate JWT>
&actor_token_type=urn:ietf:params:oauth:token-type:jwt
&audience=<target audience>
&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
&client_assertion=<Delegate client authentication>

Issued token payload (subject to the requested token type):

{
  "iss": "https://idp.example",
  "sub": "<user identifier for target audience>",
  "aud": "<target audience>",
  "client_id": "delegate-client",
  "act": {
    "iss": "https://idp.example",
    "sub": "delegate-client"
  }
}

4. Client Metadata Extensions

For Initiators

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.

For example:

{
  "iss": "https://idp.example",
  "sub": "user-123",
  "aud": "initiator-client",
  "may_act": {
    "iss": "https://idp.example",
    "sub": "delegate-client"
  }
}

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

The IdP MUST apply the following processing:

  1. Validate the subject_token signature, issuer, expiration, and other requirements applicable to its Identity Assertion type.
  2. Determine the Initiator from the validated assertion audience using the IdP's issuer-scoped client-registration mapping. If the audience is a JSON array, exactly one audience member MUST resolve to a registered OAuth client at the IdP; the IdP MUST reject the exchange when zero or more than one such registration is found.
  3. Validate actor_token according to its token type and determine the actor identity.
  4. Confirm that the actor identity matches the client authenticated for the request (the Delegate).
  5. Verify that a CCDR exists authorizing the Delegate to act for the Initiator. The IdP MUST also verify the current status of the Initiator, the Delegate, and any prior actors recorded in nested act chains within the subject token. Any ancestor that has been revoked, deprovisioned, or otherwise disallowed under current policy MUST cause the exchange to fail. See §11.9.
  6. 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.
  7. Evaluate policy over (End-User, Initiator, Delegate, requested audience, resource, scope, authorization_details) according to IdP configuration.
  8. On success, issue the requested token according to §9.

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:
"act": {
  "iss": "https://idp.example",
  "sub": "delegate-client"
}

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:

"act": {
  "iss": "https://idp.example",
  "sub": "delegate-client",
  "act": {
    "iss": "https://idp.example",
    "sub": "initiator-client"
  }
}

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 advertises support via the existing authorization_grant_profiles_supported metadata property (defined by ID-JAG) plus a companion property that describes the accepted (subject_token_type, actor_token_type) combinations under this profile.

authorization_grant_profiles_supported : The set of grant profile identifiers the authorization server supports. When the authorization server supports this profile, it MUST include this profile's identifier (TBD; example urn:ietf:params:oauth:token-exchange-profile:cross-client-delegation).

cross_client_delegation_token_types_supported : OPTIONAL. A JSON array of objects describing the (subject_token_type, actor_token_type) combinations the authorization server will accept under this profile. Each object has a subject_token_type URI and an actor_token_type URI.

Example authorization server metadata:

{
  "authorization_grant_profiles_supported": [
    "urn:ietf:params:oauth:token-exchange-profile:cross-client-delegation"
  ],
  "cross_client_delegation_token_types_supported": [
    {
      "subject_token_type": "urn:ietf:params:oauth:token-type:id_token",
      "actor_token_type": "urn:ietf:params:oauth:token-type:jwt"
    },
    {
      "subject_token_type": "urn:ietf:params:oauth:token-type:saml2",
      "actor_token_type": "urn:ietf:params:oauth:token-type:jwt"
    }
  ]
}

These metadata values indicate what the authorization server 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. Where sender constraining is used, the deployment MUST define how proof-of- possession transitions from the Initiator to the Delegate; an assertion bound only to the Initiator's key cannot be presented by the Delegate.

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 also to ancestor status. The IdP MUST re-check the current status of the Initiator, the Delegate, and any prior actors recorded in nested act chains at each mint. See §11.9.

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 Chain Revocation Propagation

Revocation of an Initiator, Delegate, or any prior actor recorded in a chain propagates only through the mint-time ancestor status check required by §8 (step 5). A token already issued cannot be revoked retroactively based on subsequent ancestor status changes. Deployments SHOULD use short exp values on issued tokens to bound the residual window of a revoked-ancestor scenario.

The same bounded window applies to may_act. A may_act claim binding is point-in-time. If the Delegate identified by a may_act claim is later revoked, tokens already minted using that assertion remain valid to their exp regardless of the revocation.

Cross-trust-domain chains cannot make the mint-time ancestor status check without reaching another authority. That constraint is a cross-domain trust establishment problem separate from this profile.

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)

This profile can be composed with ID-JAG Token Exchange. 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 1.0

Key-binding an Identity Assertion to the Initiator's key alone is not resolved by this profile: without a presenter-continuation or key-transition mechanism, the Delegate cannot demonstrate proof-of-possession for such an assertion. Deployments requiring both key binding and cross-client delegation need to define the presenter-transition mechanism via a companion profile. This remains an open problem across the delegation space and is not unique to this profile.

12.5 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

  1. Per-assertion authorization. Should profiles using OIDC require may_act, or retain the CCDR-only mode for unchanged ID Tokens?
  2. Authenticated handoff. What mechanism, if any, proves that the Initiator actively conveyed a particular assertion to the Delegate? A related sub-question: does a may_act claim signed by the assertion's issuer represent sufficient authorization to record the Initiator as a nested prior actor in act, or does the current profile's strict requirement (Initiator-authenticated evidence) hold?
  3. Relationship exposure. Should an authenticated client be able to query its own CCDRs through a protected endpoint?
  4. Actor credential types. Is an RFC 7523 client assertion sufficient for the base profile, with workload credentials and access tokens defined by companion profiles?
  5. Consent surface. Under which deployment policies is administrative authorization sufficient, and when must the delegation be shown to the End-User?
  6. Cross-organizational Delegates. How does the IdP recognize and namespace a Delegate controlled by another organization?
  7. Generic client relationships. If a broader client_relationships primitive emerges, how should CCDR be represented within it?

14. IANA Considerations

TBD. This profile may register:

  • an authorization grant profile identifier for this profile (example urn:ietf:params:oauth:token-exchange-profile:cross-client-delegation);
  • client metadata: authorized_delegates, delegate_of; and
  • authorization server metadata: cross_client_delegation_token_types_supported.

authorization_grant_profiles_supported is defined by ID-JAG; this profile uses that property without new registration.

The may_act claim and the jti claim are already registered; this profile does not request new registrations for them.

15. References

Normative: RFC 6749, RFC 7519, RFC 7523, RFC 8693, OpenID Connect Core, ID-JAG.

Informative: RFC 7591, RFC 8725, RFC 9068, draft-ietf-oauth-attestation-based-client-auth, draft-mcguinness-oauth-actor-profile, OpenID Connect Key Binding 1.0, Google Cross-Client Identity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment