| Internet-Draft | OAuth Delegation Chain | July 2026 |
| Liu, et al. | Expires 8 January 2027 | [Page] |
RFC 8693 defines the act claim for multi-hop actor
identification in JWTs but does not record per-hop policy
constraints or provide delegator cryptographic confirmation.
This specification defines the delegation_chain JWT
claim as a structured companion to act: an ordered
array of delegation records capturing the Authorization
Server's attestation, the delegated policy constraints at each
hop, and an optional delegator cryptographic confirmation.
Together, act and delegation_chain provide
both runtime authorization and verifiable delegation lineage.
The specification also defines cross-domain delegation support
and an optional user interaction mechanism for delegation
consent.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 8 January 2027.¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
In multi-agent systems, a primary agent (Agent A) may need to delegate a subset of its authorized operations to a secondary agent (Agent B), which may in turn delegate further to Agent C. Each delegation hop must preserve the original user's authorization intent while constraining what each downstream agent is permitted to do.¶
OAuth 2.0 already provides building blocks for expressing delegation.
RFC 8693 defines the act claim, which supports nested
multi-hop actor identification (enabling a token to express that
Agent A delegated to Agent B, which in turn delegated to Agent C).
[I-D.ietf-oauth-identity-chaining] defines the
cross-domain transport pattern combining Token Exchange
([RFC8693]) and JWT Authorization Grant
([RFC7523]) to carry identity and authorization
information across trust domain boundaries. Together, these
mechanisms address the runtime dimension of delegation: who is
currently acting, and how to move tokens across domains.¶
However, three structural gaps remain for agent delegation scenarios:¶
act claim
identifies the actors at each hop but does not record what
authorization constraints were applied at each delegation step.
A downstream Resource Server sees the final scope but
cannot verify whether intermediate agents narrowed or expanded
the authorization along the way.¶
act claim is constructed unilaterally by the
Authorization Server. The delegating agent leaves no independent
cryptographic evidence that it authorized a specific delegation.
This limits non-repudiation and post-hoc audit capabilities.¶
act nor identity chaining defines a mechanism for
pausing a delegation flow to obtain explicit user consent. This
is a gap specific to agent scenarios, where agents may
autonomously delegate to other agents without the user's
awareness.¶
This specification introduces the delegation_chain claim as
a structured companion to act. While act
provides runtime actor identification for authorization decisions,
delegation_chain records the full delegation history as an
ordered array of delegation records. Each record captures the
AS's attestation and, when present, the delegated policy at that
hop, and MAY additionally carry the delegator's cryptographic
confirmation,
ensuring that neither the AS nor any delegating agent can
unilaterally construct or deny a delegation record. The two claims coexist in the same token:
act answers "who is acting now" for the Resource Server,
while delegation_chain answers "how was this authorization
delegated, step by step" for verification and compliance systems.¶
The delegation_chain claim addresses the delegation lineage and verification
dimension of complex delegation, complementing the runtime semantics
provided by existing OAuth mechanisms. Cross-domain delegation
(Section 8) addresses the multi-domain scenario. This version of the specification focuses on linear
delegation chains; other complex topologies such as
diamond-shaped delegation, where multiple paths converge on the same
agent, may be addressed by future extensions.¶
Scope Boundary: This specification addresses problems that lie outside the design scope of Token Exchange ([RFC8693]) and Identity Chaining ([I-D.ietf-oauth-identity-chaining]). Token Exchange defines how to convert one token into another but does not record the delegation lineage across multiple hops. Identity Chaining defines how to transport identity across trust domains but intentionally leaves Claims Transcription representation undefined. The three problems solved by this specification (multi-hop delegation lineage, delegator non-repudiation, and delegation consent interaction) are orthogonal to both token conversion and cross-domain transport. Absorbing this mechanism into either existing specification would broaden their scope beyond their original design intent and impose delegation lineage complexity on deployments that do not need it.¶
Relationship to Compositional Approaches:
[I-D.klrc-aiagent-auth] demonstrates how
existing OAuth mechanisms — Token Exchange, Transaction
Tokens, and CIBA — can be composed to address agent
authentication and authorization. This specification
complements that compositional approach by defining the
delegation lineage layer that composition of existing
mechanisms alone does not provide: per-hop delegator
cryptographic confirmation and verifiable delegation
history. The two approaches are designed to coexist —
compositional frameworks provide the transport and runtime
semantics, while delegation_chain provides the
structured delegation record and non-repudiation layer.¶
Deployment Options: A minimal deployment
requires only the delegation_chain claim structure
(Section 4), the delegation
Token Exchange flow (Section 6), and
the AS validation rules
(Section 5.2).
Implementations MAY additionally support structured policy
(delegated_policy), user interaction
(Section 5), cross-domain
delegation (Section 8),
delegator_signature, and authorization evidence
propagation, depending on deployment requirements.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals.¶
This section describes how the delegation_chain claim
relates to existing OAuth 2.0 mechanisms, establishing the precise
boundary between runtime delegation semantics and structured
delegation records.¶
RFC 8693 defines the act claim to express that delegation
has occurred and to identify the acting party. The act
claim supports nested multi-hop actor chains: a token can express
that Agent A delegated to Agent B, which delegated to Agent C, all
within a single nested JSON structure. This nesting enables
Resource Servers to identify the current actor and trace the actor
lineage for authorization decisions.¶
The act claim is constructed by the Authorization Server
alone: the AS assembles the nested actor chain without requiring
independent proof from each delegating agent. This is sufficient
for runtime authorization decisions but does not capture per-hop
policy constraints or delegator consent.¶
The delegation_chain claim complements act by
recording the delegation lineage as a structured array of
records. Each record captures, when present, the AS's per-hop
attestation (as_signature), the policy constraints
applied at that hop (scope, and, when present,
delegated_policy), and the delegator's own
cryptographic proof (delegator_signature). This
enables:¶
delegator_signature on each record provides
independent evidence of each delegator's consent, enabling
non-repudiation that the AS alone cannot provide.¶
act.¶
In a token carrying both claims, act identifies the
current actor for the Resource Server's authorization decision,
while delegation_chain provides the structured delegation
record from the current actor back to the original human principal.
The delegatee_id of the most recent delegation record
(index 0) MUST match the act.sub value, ensuring
continuity between the two claims. delegation_chain
is thus a companion claim that preserves act's
original RFC 8693 semantics (current actor identification)
while adding multi-hop delegation history as a separate,
independently verifiable structure.¶
[I-D.ietf-oauth-identity-chaining] defines a general-purpose pattern for preserving identity and authorization information across trust domains, combining Token Exchange ([RFC8693]) and JWT Authorization Grant ([RFC7523]). It addresses the transport dimension of cross-domain delegation: how to move a token from Domain A to Domain B while preserving the user identity and authorization context.¶
This specification reuses the identity chaining transport for cross-domain delegation (Section 8) and adds agent-specific extensions:¶
scope equal to or narrower than its
predecessor; structured policy
(delegated_policy) is additionally enforced when
present;¶
delegator_signature rely on AS signature alone;¶
The key distinction in deployment context is scope: identity chaining addresses general cross-domain identity propagation (human users, CI/CD pipelines, SSO extension), while this specification profiles that transport specifically for agent-to-agent delegation with delegation lineage requirements.¶
Section 2.5 of [I-D.ietf-oauth-identity-chaining] defines Claims Transcription (the process by which Authorization Servers add, change, or remove claims when producing JWT authorization grants or access tokens during cross-domain flows). That specification explicitly leaves the representation of transcribed claims undefined: "The representation of transcribed claims and their format is not defined in this specification."¶
The delegation_chain claim provides one such
representation. When delegation crosses a trust domain boundary,
each delegation record captures the transcribed policy
(when present, delegated_policy) and the cryptographic evidence of the
transcribing parties (the AS via as_signature and the
delegator via delegator_signature, each when present).
This enables the receiving
domain to verify not just what was transcribed but
who authorized the transcription and under what
constraints, closing the representation gap left by identity
chaining.¶
Implementations using identity chaining for cross-domain delegation
SHOULD include the delegation_chain claim in the JWT
authorization grant as a structured Claims Transcription format,
enabling the receiving AS to validate the delegation lineage before
issuing a local access token.¶
wit://) and SPIFFE
IDs (spiffe://).
The identifier MUST be resolvable to a verifiable public key
for signature verification when
delegator_signature is present.¶
The delegation_chain is an ordered array of delegation records,
from most recent to earliest. Each record represents one delegation hop.¶
The following example shows a delegation record with WIT-based agent identifiers, a machine-enforceable structured policy, a root evidence reference, and dual signatures:¶
{
"delegation_chain": [
{
"delegator_id": "wit://agent-a.example/sha256.aaa111...",
"delegatee_id": "wit://agent-b.example/sha256.bbb222...",
"as_id": "https://as.example.com",
"delegation_timestamp": 1734516900,
"root_evidence_ref": "evidence-root-abc123",
"delegated_policy": {
"type": "rego",
"content": "package agent\ndefault allow = false\n\nallow if {\n input.action == \"inventory_check\"\n input.item_id == \"123\"\n}",
"entry_point": "allow"
},
"operation_summary": "Delegate inventory check for item 123",
"delegator_signature": "eyJhbGciOiJFUzI1NiJ9..MEYCIQD...",
"as_signature": "eyJhbGciOiJSUzI1NiJ9..MEUCIQDx..."
}
]
}
A delegation record transitions through four phases during its lifecycle:¶
interaction_required response (see
Section 5).
A similar interaction response mechanism for the JWT
Authorization Grant is described in
[I-D.parecki-oauth-jwt-grant-interaction-response].
The delegating agent launches the interaction URI so the user can
review and approve the delegation. Upon user approval, the agent
retries the delegation request. This phase is skipped when the AS
determines that no additional user interaction is needed (e.g., the
delegation is covered by a standing authorization or the policy has
been pre-approved). Implementations that do not require
user interaction MAY omit this phase entirely.¶
delegation_chain claim, enabling multi-hop propagation
within or across trust domains.¶
This four-phase model ensures cryptographic binding between user authorization, agent identity, and policy constraints throughout the delegation chain, with explicit user interaction support when required.¶
| Field | Type | Requirement | Description |
|---|---|---|---|
| delegator_id | string | REQUIRED |
A URI identifying the delegating agent. This
specification defines two URI schemes:
wit:// (WIT URI) and spiffe://
(SPIFFE ID). The URI MUST be resolvable to a
verifiable public key for
delegator_signature verification.
|
| delegatee_id | string | REQUIRED |
A URI identifying the receiving agent. The same
URI scheme considerations as
delegator_id apply.
|
| delegation_timestamp | NumericDate | REQUIRED | When this delegation was authorized. |
| scope | string | OPTIONAL |
The delegated scope at this hop, expressed as a
space-delimited list of scope values
([RFC6749], Section 3.3). When present,
this field captures the scope explicitly authorized by
the delegator and is included in the signature
computation to prevent scope expansion by a compromised
AS. When omitted, the delegated scope is conveyed
through the access token's scope claim and
the delegated_policy field (if present).
|
| delegated_policy | object | OPTIONAL | A machine-readable expression of the authorization constraints that apply to this delegation hop. The delegated policy MUST be equal to or more restrictive than the delegator's policy; policy or scope expansion is not allowed. See below for deployment-specific structure. |
| operation_summary | string | OPTIONAL | Human-readable description of delegated operation. |
| root_evidence_ref | string | CONDITIONAL |
An opaque identifier referencing the root authorization
event (the original consent granted by the human
principal from which all delegations in the chain
derive). This field MUST be present for the first
delegation (User to Agent A) when structured evidence
is used and
SHOULD be propagated through the chain. The format of
the identifier and the mechanism for resolving it are
deployment-specific: implementations using a structured
authorization evidence model (such as the one described
in [I-D.liu-oauth-authorization-evidence])
SHOULD set this value to the evidence.id from
the root token; other deployments MAY use any stable,
unique identifier (e.g., a consent record ID or an
audit log entry reference) that enables post-hoc
retrieval of the original authorization context. Implementations not using structured authorization evidence MAY omit this field.
|
| delegator_signature | string | RECOMMENDED |
Cryptographic signature from the delegating agent's
private key over this delegation record. This provides
dual-signature security alongside
as_signature, preventing a malicious AS from
forging unauthorized delegations and ensuring
non-repudiation. Implementations SHOULD
include this field on every delegation record. It MAY be
omitted when the AS is the sole trust anchor and the
deployment does not require independent delegator
non-repudiation.
|
| as_id | string | REQUIRED |
An identifier for the Authorization Server that
created this delegation record. This value MUST
match the iss claim of the token in which
this record first appeared. In cross-domain chains
where records may originate from different
Authorization Servers, the as_id enables
the Resource Server to select the correct public
key for as_signature verification.
|
| as_signature | string | RECOMMENDED | AS signature over this delegation record. When all delegation hops occur within a single trust domain under one Authorization Server, the AS's signature over the issued token already attests to the entire chain and this per-hop signature MAY be omitted. It is RECOMMENDED when delegation crosses trust domain boundaries, so the receiving domain can independently verify each hop. |
The structure of the delegated_policy field depends
on the deployment profile:¶
scope parameter, and the Resource Server applies
scope-based authorization. When this field is absent, the
Resource Server MUST apply scope-based authorization only.¶
type, content, and
entry_point sub-fields, as described in
[I-D.liu-oauth-rego-policy]).¶
The delegation_timestamp MUST satisfy the following
constraints:¶
iat (issued at) claim, since the delegation event
occurs before or at the time the token is issued;¶
delegation_timestamp of the temporally earlier
delegation record (the record at the next higher array
index), ensuring
that timestamps are monotonically non-increasing from index 0
(most recent) to index N (earliest);¶
iat and
less than or equal to the delegator token's exp).¶
The as_signature and delegator_signature, when
present, MUST be computed over the same set of fields.
The signature is a JWS ([RFC7515]) compact
serialization. The JWS payload is a JSON object
containing exactly the following fields (omitting OPTIONAL
fields that are absent):¶
delegator_id¶
delegatee_id¶
as_id¶
delegation_timestamp¶
scope (if present)¶
delegated_policy (if present)¶
operation_summary (if present)¶
root_evidence_ref (if present)¶
Both signature fields MUST be excluded from their respective
signature computations. The JWS alg header MUST
be set appropriately (e.g., RS256 for AS signatures, ES256
for delegator signatures). The JWS kid header
SHOULD be included to facilitate key resolution. The
resulting compact JWS string is stored as the value of the
respective signature field. When verifying, the verifier
decodes the JWS payload and confirms that the decoded JSON
object matches the delegation record fields.¶
When the delegator_signature is present (RECOMMENDED),
it uses the delegating agent's agent-identifier-bound
private key, while as_signature uses the Authorization Server's
signing key. This dual-signature approach, when both signatures are
present, ensures:¶
The need for per-hop signatures depends on deployment scope.
When all delegation hops occur within a single trust domain
under one Authorization Server, the AS's signature over the
issued token already attests to the entire delegation chain,
and per-hop as_signature and
delegator_signature MAY be omitted without loss of
integrity. Per-hop signatures become valuable when delegation
crosses trust domain boundaries — where the receiving domain
must independently verify each hop's authorization — or when
non-repudiation from the delegator is required for compliance
or audit. This scoping keeps the mechanism lightweight for
intra-domain deployments while preserving strong guarantees
for cross-domain agent delegation.¶
The delegator_signature (and any verification of the
delegatee's identity) requires the relying party to resolve
the agent identifier to a verifiable public key. The
resolution mechanism depends on the URI scheme used in the
delegator_id or delegatee_id field:¶
Implementations SHOULD document the supported URI schemes and
their resolution mechanisms in deployment-specific
configuration. If the relying party cannot resolve the agent
identifier to a trusted public key, it MUST treat the
delegator_signature as unverifiable.¶
The array MUST be ordered from most recent delegation to earliest:¶
This ordering allows efficient validation starting from the immediate delegator.¶
This section defines the delegation flow with explicit user
interaction, used when the Authorization Server determines that
user consent is required before delegation. It defines
the interaction response mechanism for OAuth 2.0 Token Exchange
requests
([RFC8693], grant_type=token-exchange).
A similar mechanism for the JWT Authorization Grant
([RFC7523], grant_type=jwt-bearer) is
described in
[I-D.parecki-oauth-jwt-grant-interaction-response].¶
The user interaction mechanism ensures that delegation decisions remain under user control even in complex multi-agent scenarios. When the Authorization Server determines that user interaction is required, the flow includes an explicit consent step before token issuance.¶
+--------+ +---------+ +--------+ +---------+ +---------+
| User | | Agent A | | AS | | Agent B | | RS |
+--------+ +---------+ +--------+ +---------+ +---------+
| | | | |
| (1) Initial | | | |
| Authorization | | | |
| (OAuth flow) | | | |
|---------------> | | | |
| | | | |
| | (2) Token A | | |
| | (root, no | | |
| | chain) | | |
| |<----------------| | |
| | | | |
| | (3) Token Exchange (delegation) | |
| |---------------->| | |
| | - subject_token | |
| | - delegatee_id | |
| | - authorization_details | |
| | | | |
| | (4) AS determines user interaction required |
| | interaction_required | |
| | interaction_uri | |
| | interval=5 | |
| |<----------------| | |
| | | | |
| (5) Launch | | | |
| interaction | | | |
|<----------------| | | |
| | | | |
| (6) Review & | | | |
| Approve | | | |
| delegation | | | |
|---------------------------------->| | |
| | | | |
| | (7) Redirect | | |
| |<----------------| | |
| | | | |
| | (8) Retry Token Exchange | |
| |---------------->| | |
| | | | |
| | | (9) Validate | |
| | | - Interaction | |
| | | completed | |
| | | - Token A valid| |
| | | - Scope subset | |
| | | | |
| | | (10) Issue Token B |
| |<----------------| | |
| | with delegation_chain | |
| | (10.5) Transfer to Agent B | |
| |--------------------------------->| |
| | | | |
| | | | (11) API Request|
| | | |---------------->|
| | | | |
| | | | (12) Validate |
| | | | chain |
| | | |<----------------|
Agent A obtains authorization from the user through a standard OAuth
flow. The resulting token does not contain a delegation_chain
(it is the root authorization).¶
Agent A initiates delegation using OAuth 2.0 Token Exchange [RFC8693]. The request includes delegation-specific parameters to identify the delegatee and the delegated policy.¶
The following example shows a
delegation request with WIT-based agent identity, client
attestation, and a structured policy carried via
authorization_details:¶
POST /token HTTP/1.1 Host: as.example.com Content-Type: application/x-www-form-urlencoded OAuth-Client-Attestation: eyJ0eXAiOiJ3aXQrand0IiwiYWxnIjoiRVMyNTYifQ... OAuth-Client-Attestation-PoP: eyJ0eXAiOiJvYXV0aC1jbGllbnQtYXR0ZXN0... grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange &subject_token=eyJhbGciOiJSUzI1NiJ9... &subject_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Aaccess_token &requested_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Ajwt &scope=cart%3Aread &authorization_details=%5B%7B%22type%22%3A%22rego_policy%22%2C%22policy%22 %3A%7B%22type%22%3A%22rego%22%2C%22content%22%3A%22package+agent...%22%2C %22entry_point%22%3A%22allow%22%7D%7D%5D &delegatee_id=wit%3A%2F%2Fagent-b.example%2Fsha256.bbb222...
This specification defines the following extension parameter for use with Token Exchange [RFC8693] requests:¶
delegatee_id field
in the delegation_chain record.¶
The standard and extension parameters in the request are:¶
subject_token: Agent A's current access token;¶
subject_token_type:
urn:ietf:params:oauth:token-type:access_token;¶
authorization_details (OPTIONAL): Carries the delegated
policy in a structured format (e.g., type "rego_policy"), which
MUST be equal to or more restrictive than Agent A's policy;¶
delegatee_id: The agent identifier URI of the delegatee agent
(Agent B);¶
scope (OPTIONAL): Requested scope for the
delegated token, which MUST be a subset of Agent A's scope.¶
requested_token_type (OPTIONAL): Defaults to
urn:ietf:params:oauth:token-type:jwt.
Because the delegation_chain claim MUST be
embedded in a JWT, implementations using this
specification MUST request JWT-format access tokens.
The value urn:ietf:params:oauth:token-type:jwt
is REQUIRED when the delegation_chain claim is
expected in the response.¶
resource (OPTIONAL): The identifier of the target
Authorization Server when the delegation crosses a trust domain
boundary, as defined in [I-D.ietf-oauth-identity-chaining].
When present, the AS issues a JWT authorization grant suitable for
presentation to the target AS instead of a direct access token.¶
audience (OPTIONAL): A well-known or logical name of
the target Authorization Server, as an alternative to
resource for cross-domain delegation. One of
resource or audience is REQUIRED when the
delegation targets an agent in a different trust domain.¶
interaction_callback_uri (OPTIONAL): The URI to which the AS will
redirect the user's browser after a delegation interaction is
complete, as specified in
Section 5.3.
A similar parameter is described in
[I-D.parecki-oauth-jwt-grant-interaction-response].
This parameter is used in conjunction with the
interaction_required response to signal
the client that user interaction has been completed.¶
When the Authorization Server determines that user interaction
is required (see
Section 5.9 for the
decision criteria), the AS responds with an
interaction_required error containing:¶
interaction_uri: The URI where the user reviews and approves the delegation;¶
interval: The minimum polling interval in seconds (default: 5);¶
expires_in: The number of seconds until the interaction session expires.¶
This specification defines
the interaction response mechanism for delegation Token Exchange
requests
([RFC8693], grant_type=token-exchange). A
similar mechanism for the JWT Authorization Grant
(RFC 7523, grant_type=jwt-bearer) is described in
[I-D.parecki-oauth-jwt-grant-interaction-response].
The response semantics defined here are applicable to Token Exchange
requests. The AS associates the interaction session with the Token Exchange
request parameters (including the subject_token,
delegatee_id, and requested delegation policy) so that upon
user approval, the same Token Exchange request can be retried to
obtain the delegated token.¶
Agent A launches the interaction_uri in the user's browser,
where the AS presents the delegation details for user review:¶
The user reviews the delegation details and approves or denies
the delegation request. If the client provided an
interaction_callback_uri, the AS redirects the user's
browser to that URI as a signal that the interaction is complete.¶
Agent A retries the original Token Exchange request (with the same parameters). The AS recognizes the associated interaction session and proceeds with validation.¶
While the interaction is pending, subsequent Token Exchange requests
from Agent A with the same parameters SHOULD return an
interaction_pending error. The agent MUST wait at least
the number of seconds specified by the interval parameter
between polling requests.¶
The AS MUST perform the following validations:¶
delegatee_id) to
confirm the delegatee is authentic and currently active.¶
delegation_chain claim, verify
the chain's continuity, signatures, and policy narrowing
as defined in Section 9. If
validation fails, reject the request with an
invalid_delegation_chain error.¶
delegation_timestamp in the proposal (or the
request time as observed by the AS) is outside an
acceptable time window. A RECOMMENDED maximum skew is 5
minutes. This prevents replay of previously captured
delegation requests.¶
Upon successful validation, the AS issues a new token for Agent B with:¶
Agent B uses the delegated token to access resources at the Resource
Server (RS). The RS validates the token and verifies the
delegation_chain as defined in
Section 9.¶
The Authorization Server has discretion in determining when the Delegation Interaction Phase is triggered. The following guidance is provided to help AS implementations make consistent decisions:¶
In scenarios where user interaction is not required (for example, when the delegation is covered by a standing authorization or the policy has been pre-approved), the AS MAY skip the user interaction step and proceed directly with token issuance. This simplified flow reduces latency and user friction for routine delegation scenarios.¶
When none of the conditions listed in
Section 5.9 apply, the AS responds to the
Token Exchange request with a success response containing the delegated
token, bypassing the interaction_required step.¶
+--------+ +---------+ +--------+ +---------+ +---------+
| User | | Agent A | | AS | | Agent B | | RS |
+--------+ +---------+ +--------+ +---------+ +---------+
| | | | |
| (1) Initial | | | |
| Authorization | | | |
| (OAuth flow) | | | |
|---------------->| | | |
| | | | |
| | (2) Token A | | |
| | (root, no | | |
| | chain) | | |
| |<----------------| | |
| | | | |
| | (3) Token Exchange (delegation) | |
| |---------------->| | |
| | - subject_token | |
| | - delegatee_id | |
| | - authorization_details | |
| | | | |
| | | (4) Validate | |
| | | - Token A valid| |
| | | - Scope subset | |
| | | - Standing auth| |
| | | or pre-approved |
| | | | |
| | | (5) Issue Token B |
| |<----------------| | |
| | with delegation_chain | |
| | (5.5) Transfer to Agent B | |
| |--------------------------------->| |
| | | | |
| | | | (6) API Request|
| | | |---------------->|
| | | | |
| | | | (7) Validate |
| | | | chain |
| | | |<----------------|
The Token Exchange request format, parameters, and validation rules are identical to those defined in Section 5. The only difference is that the AS does not require user interaction before issuing the delegated token.¶
This simplified flow is appropriate when:¶
Authorization Servers SHOULD log all decisions to skip user interaction as part of their audit log. The specific mechanism for recording skip decisions is deployment-specific: implementations MAY record them in an application-specific audit log or other deployment-specific evidence model.¶
When the AS issues a delegated token, it extends the delegation_chain:¶
When the AS issues a delegated token within the same trust
domain and structured authorization evidence is used, it
SHOULD propagate the evidence
claim from the subject token (or root
token) into the newly issued delegated token. This ensures that Resource Servers can verify the
original user consent without needing to retrieve the root
token separately. When evidence is propagated, the
root_evidence_ref field in each delegation record
SHOULD match the evidence.id value in the propagated
evidence claim. For cross-domain evidence propagation, see
Section 8.¶
Implementations not using structured authorization evidence
are not required to carry evidence
claims. In
deployments that do not use structured authorization evidence,
the root_evidence_ref field (when present) serves as
an opaque reference to the original authorization event,
resolvable through deployment-specific mechanisms such as an
audit log query or a consent management API.¶
If Agent A's token has no delegation_chain (root authorization), the
AS creates a new chain with one entry. The following shows an
extended first delegation record:¶
{
"delegation_chain": [
{
"delegator_id": "wit://agent-a.example/sha256.aaa111...",
"delegatee_id": "wit://agent-b.example/sha256.bbb222...",
"as_id": "https://as.example.com",
"delegation_timestamp": 1734516900,
"root_evidence_ref": "evidence-root-abc123",
"delegated_policy": {
"type": "rego",
"content": "package agent\ndefault allow = false\n\nallow if {\n input.action == \"cart_op\"\n}",
"entry_point": "allow"
},
"operation_summary": "Delegate cart operations",
"delegator_signature": "eyJhbGciOiJFUzI1NiJ9..MEYCIQD...",
"as_signature": "eyJhbGciOiJSUzI1NiJ9..MEUCIQDx..."
}
]
}
A minimal equivalent would carry only
delegator_id, delegatee_id,
as_id,
delegation_timestamp, operation_summary,
and as_signature, with the delegated scope expressed
via the token's scope claim (e.g.,
cart:read).¶
If Agent B further delegates to Agent C, the AS prepends a new record. The following shows an extended two-hop chain:¶
{
"delegation_chain": [
{
"delegator_id": "wit://agent-b.example/sha256.bbb222...",
"delegatee_id": "wit://agent-c.example/sha256.ccc333...",
"as_id": "https://as.example.com",
"delegation_timestamp": 1734517800,
"root_evidence_ref": "evidence-root-abc123",
"delegated_policy": {
"type": "rego",
"content": "package agent\ndefault allow = false\n\nallow if {\n input.action == \"inventory_check\"\n input.item_id == \"123\"\n}",
"entry_point": "allow"
},
"operation_summary": "Check inventory for item 123",
"delegator_signature": "eyJhbGciOiJFUzI1NiJ9..MEYCIQD...",
"as_signature": "eyJhbGciOiJSUzI1NiJ9..MEUCIQDx..."
},
{
"delegator_id": "wit://agent-a.example/sha256.aaa111...",
"delegatee_id": "wit://agent-b.example/sha256.bbb222...",
"as_id": "https://as.example.com",
"delegation_timestamp": 1734516900,
"root_evidence_ref": "evidence-root-abc123",
"delegated_policy": {
"type": "rego",
"content": "package agent\ndefault allow = false\n\nallow if {\n input.action == \"cart_op\"\n}",
"entry_point": "allow"
},
"operation_summary": "Delegate cart operations",
"delegator_signature": "eyJhbGciOiJFUzI1NiJ9..MEYCIQD1...",
"as_signature": "eyJhbGciOiJSUzI1NiJ9..MEUCIQDx..."
}
]
}
With scope-based delegation, the same two-hop chain
would omit delegated_policy,
delegator_signature, and
root_evidence_ref from each record. The scope
narrowing (e.g., cart:read inventory:read to
inventory:read:item:123) is expressed solely via
each delegated token's scope claim.¶
When delegation hops span multiple trust domains (each with its own
Authorization Server), this specification combines the
delegation_chain mechanism with the cross-domain transport
pattern defined in [I-D.ietf-oauth-identity-chaining].¶
The grant type used for delegation depends on the trust domain boundary:¶
grant_type=token-exchange) as defined in
Section 6. Both delegator and delegatee
agents trust the same Authorization Server, which can validate
the subject token and issue a delegated token directly.¶
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer)
at the receiving AS.
When agents belong to different trust domains with different
Authorization Servers, the originating AS cannot issue a
direct access token for the remote domain. Instead, the
delegating agent initiates a Token Exchange request at the
originating AS, which returns a signed JWT authorization
grant. The delegatee agent then presents this grant to its
local AS using the JWT Bearer grant type. The receiving AS
verifies the grant using the originating AS's public key
(obtained via [RFC8414] metadata) and issues
a local access token.¶
Consider an agent in Trust Domain A that needs to delegate a subset of its authorization to an agent in Trust Domain B:¶
+-------+ +-------+ +-------+ +-------+ +-------+ +-------+
| User | |Agent A| | AS-A | |Agent B| | AS-B | | RS-B |
+-------+ +-------+ +-------+ +-------+ +-------+ +-------+
| | | | | |
| (1) Auth | | | | |
|--------->| | | | |
| | | | | |
| | (2) Token Exchange | | |
| | (delegation + | | |
| | resource=AS-B) | | |
| |--------->| | | |
| | | | | |
| | (3) JWT | | | |
| | Authoriz | | | |
| | Grant | | | |
| |<---------| | | |
| | | | | |
| | (3.5) Agent A transfers JWT Grant to Agent B |
| |-------------------->| | |
| | | | | |
| | | | (4) Present JWT Grant |
| | | |--------->| |
| | | | | |
| | | | |(5) Validate |
| | | | |- JWT signature|
| | | | |- delegation |
| | | | |- policy |
| | | | | |
| | | | |(6) Access |
| | | | | Token |
| | | |<---------| |
| | | | | |
| | | |(7) API Req |
| | | |------------------------>|
| | | | | |
delegation_chain).¶
resource parameter set to AS-B's
identifier (as defined in
[I-D.ietf-oauth-identity-chaining]) and the
delegatee_id parameter identifying Agent B. This
signals that the delegation targets an agent in Trust Domain B.¶
delegation_chain claim. If user interaction is
required, the interaction flow described in Section 5 is
used before this step.¶
delegation_chain (including AS-A's signature on
each record), and confirms policy narrowing constraints.¶
delegation_chain claim from the
JWT authorization grant.¶
For cross-domain delegation to function, the following trust requirements MUST be satisfied:¶
as_signature on delegation records
issued by AS-A. This trust relationship is typically established
through key exchange or by publishing AS-A's public keys via
Authorization Server Metadata ([RFC8414]).¶
delegation_chain claim from the JWT authorization
grant into the access token it issues, so that Resource Servers
in Trust Domain B can validate the full delegation lineage.¶
evidence claim from the JWT
authorization grant, enabling Resource Servers in Trust Domain B
to verify the original user consent without contacting AS-A.
This is a SHOULD rather than a MUST because cross-domain
evidence propagation may be constrained by data minimization
policies, privacy regulations, or trust agreements between
domains. When evidence is not propagated, Resource Servers in
Trust Domain B MUST rely on back-channel verification with AS-A
or AS-B to validate the original user consent.¶
scope is equal to or narrower than
the scope in the JWT authorization grant; scope expansion
across domain boundaries is not permitted. When the
delegated_policy field is present, AS-B SHOULD
additionally verify that the policy has not been expanded.
The mechanism for policy comparison is implementation-
specific: for simple policy representations, a structural
comparison may suffice; for expressive policy languages
such as Rego or ALFA, the receiving AS MAY rely on the originating
AS's attestation (via as_signature) rather than
performing an independent policy-subset check, which may be
computationally intractable for arbitrary policies.¶
When a delegation chain spans multiple domains, each domain's AS
may add delegation records to the chain. The cross-domain transport
uses the identity chaining pattern (Token Exchange + JWT Bearer
Grant) at each domain boundary, while the delegation_chain
accumulates records from all domains.¶
Resource Servers validating a cross-domain delegation chain MUST:¶
Section 2.5 of [I-D.ietf-oauth-identity-chaining]
describes Claims Transcription (the process by which Authorization
Servers add, change, or remove claims during cross-domain token
flows) but leaves the representation of transcribed claims
undefined. The delegation_chain claim provides one such
representation: when delegation crosses a trust domain boundary,
each delegation record captures the transcribed policy
(when present, delegated_policy), the identity mapping (delegator and
delegatee identifiers), and the cryptographic evidence of both the
transcribing AS (as_signature) and, when present, the
delegating agent (delegator_signature).¶
This enables the receiving domain's AS (AS-B) to verify not just
what claims were transcribed but who authorized the
transcription and under what constraints, closing the
representation gap left by the base identity chaining
specification. AS-B SHOULD validate the delegation_chain
records from AS-A as part of its Claims Transcription processing
before issuing a local access token.¶
Resource Servers validate the delegation_chain as follows:¶
For each record in the chain, verify the
as_signature, when present, using the public key of
the AS identified by the record's as_id field. In
single-domain chains, as_id matches the token's
iss claim. In cross-domain chains, different records
may carry different as_id values, and the Resource
Server MUST select the corresponding AS public key for each
record. In cross-domain chains, the Resource Server does not
need to verify that upstream records' as_id values
match the current token's iss claim; the
as_id is used solely to select the correct public
key for as_signature verification. When the
as_signature is present, verification ensures:¶
When as_signature is omitted on a record, the
record's integrity is still protected by the token-level JWT
signature, which covers the entire
delegation_chain claim as a single unit. Omitting
as_signature is typical in single-domain
deployments where the token issuer's signature already
attests to every record; per-record
as_signature is RECOMMENDED in cross-domain or
multi-AS deployments where independent per-hop attestation
adds assurance.¶
The last record in the chain (highest index) represents the earliest
delegation. Its delegator_id identifies the agent that holds
the root authorization (the token directly authorized by the user).¶
The Resource Server SHOULD verify the root authorization
anchor. Since the RS typically observes only the delegated
token (which carries the delegation_chain), it does
not have direct access to the root token. Verification can
be performed through one or more of the following means:¶
delegator_id of
the last chain record) holds a valid, non-revoked root
token issued by a trusted AS;¶
delegation_chain itself: the AS that issued the
delegated token has already verified the root token's
validity at issuance time, and, when present, the
as_signature on each record attests to that
verification. Even without per-record
as_signature, the token-level JWT signature
covers the entire delegation_chain array,
binding the issuance attestation to the token as a whole.¶
In deployments using structured authorization evidence,
the Resource Server SHOULD additionally
verify that the root token contains a valid evidence
claim (as described in
[I-D.liu-oauth-authorization-evidence] or an
equivalent structured evidence model), providing cryptographic
proof of user consent. Deployments that do not carry
structured evidence MAY rely on the
root_evidence_ref field as an opaque pointer to the
original authorization event, resolvable through
deployment-specific mechanisms.¶
If the RS cannot establish confidence in the root authorization anchor through any available mechanism, it SHOULD reject the request.¶
For each delegation record, when the
as_signature field is present, the Resource Server
SHOULD verify it using the Authorization Server's public
key. When the delegator_signature field is
present, the Resource Server SHOULD additionally verify it
using the delegating agent's public key (resolved as
described in the Key Resolution section above). In
single-domain deployments where the token issuer's JWT
signature already covers every record, per-record
as_signature verification is not required; the
token-level signature provides sufficient integrity.¶
When both signatures are present and verified, the dual-signature mechanism prevents:¶
Deployments that rely solely on
as_signature accept the AS as the single trust
anchor for delegation records. This is appropriate when the
AS is operated by a trusted authority and the deployment does
not require independent delegator non-repudiation.¶
Deployments that omit as_signature on some or all
records rely on the token-level JWT signature as the sole
integrity mechanism for the delegation_chain array.
This is appropriate in single-domain deployments where one
AS issues the token and attests to every delegation record
through its token-level signature; it is also the minimal
configuration that retains chain integrity, tamper
detection, record removal detection, and reorder detection,
as those properties are enforced by the token-level
signature covering the array as a whole.¶
The Resource Server SHOULD verify the current status of all
agent identifiers referenced in the
delegation_chain. The verification mechanism
depends on the identifier scheme:¶
If any agent identifier in the chain has been revoked or its
associated key material has expired, the entire
delegation_chain MUST be considered invalid, even if
individual records remain cryptographically valid.¶
Verify the chain is continuous:¶
i (where i > 0),
record[i].delegatee_id MUST equal
record[i-1].delegator_id, ensuring that the agent
who received authorization in one hop is the same agent that
delegates in the next hop;¶
delegatee_id of the most recent delegation record
(index 0) matches the token's act.sub;¶
The Resource Server validates that authorization constraints have not been expanded along the chain:¶
scope of each
delegated token MUST be equal to or a subset of the scope
of the preceding token in the chain. The final token's
scope MUST cover the requested operation. Scope expansion
at any hop invalidates the chain.¶
delegated_policy field is present, the
Resource Server SHOULD verify that each hop's policy is
equal to or more restrictive than its predecessor's policy.
The mechanism for this comparison is implementation-
specific. For expressive policy languages where automated
subset checking is computationally expensive or
undecidable, the RS MAY rely on the AS's attestation
(as_signature) as evidence that the AS already
performed policy narrowing validation at issuance time.¶
The security considerations of [RFC8693] and [RFC7519] apply to this specification. The following considerations follow the guidelines in [RFC3552].¶
This section describes the threat model underlying the
delegation_chain mechanism and the security properties it
provides.¶
Trusted Entities:¶
Adversary Capabilities:¶
delegation_chain to claim authorization it does not
possess.¶
as_signature accept the AS as the sole trust anchor
and must ensure AS compromise detection through other
operational controls.¶
Security Objectives: The
delegation_chain claim provides the following security
properties:¶
delegator_signature is present, it provides
independent evidence that the delegation was explicitly
authorized by the delegator. When omitted, deployments
rely on AS audit logs for non-repudiation.¶
delegated_policy field is
present, policy narrowing provides
additional fine-grained enforcement.¶
The AS MUST ensure that delegation cannot expand privileges:¶
Chain integrity is primarily ensured by the token-level JWT
signature, which covers the entire
delegation_chain claim as a single unit. When the
per-record as_signature is present, it provides an
additional layer of per-hop attestation. Together, these
mechanisms enforce chain integrity through the following
properties:¶
as_signature is present, it
adds an independent per-record attestation that also
requires the AS's key.¶
delegator_id, delegatee_id,
scope, and delegated_policy)
invalidates the token-level JWT signature, and, when
present, the record-level as_signature as well.¶
delegation_chain
claim as a single unit; any modification to the array
length or contents invalidates the token signature.¶
delegation_chain array in its exact serialized
form; any reordering invalidates the token signature.¶
The four properties above hold for every deployment,
including the minimal single-domain configuration in which
as_signature is omitted on all records. Adding
per-record as_signature in cross-domain or
multi-AS deployments strengthens forgery prevention and
tamper detection by providing independent per-hop
attestation that survives token re-issuance.¶
Additionally, the Resource Server SHOULD verify that the
delegation_timestamp on each record falls within a
reasonable window relative to the token's iat
(issued-at) claim. Timestamps that significantly predate
the token's issuance or fall in the future may indicate
a manipulated or replayed delegation record.¶
A malicious agent may attempt to present a token with a truncated
or empty delegation_chain to hide intermediate delegation
hops. For example, an agent holding a token with chain
[A→B→C] (three records: C←B, B←A, User→A) could attempt to
present only the most recent record [C←B] or an empty chain,
thereby concealing the earlier hops from the Resource Server.¶
This attack is prevented by the following mechanisms:¶
delegation_chain claim)
using its private key. Any modification to the
delegation_chain claim (including removal of records
or replacement with a shorter chain) invalidates the token's
signature. The Resource Server MUST reject tokens whose
signature does not verify.¶
For opaque (non-JWT) access tokens, the Resource Server MUST use
token introspection ([RFC7662]) to retrieve the
authoritative delegation_chain from the AS, rather than
trusting any client-supplied chain data.¶
A delegation chain may contain privacy-sensitive information
and, to prevent disclosure to unintended parties, should only
be transmitted over encrypted channels, such as Transport
Layer Security (TLS). All claims in a signed but unencrypted
JWT (JWS, [RFC7515]) are Base64URL-encoded and
readable by any party that obtains the token, including the
full delegation topology (all agent identities), business
policy logic (delegated_policy), operation
descriptions (operation_summary), and authorization
event references (root_evidence_ref).¶
In cases where it is desirable to prevent disclosure of
delegation records to unintended parties, the JWT should be
encrypted using JWE ([RFC7516]) with nested
JWT processing (JWE(JWS(payload))), so that only the
intended Resource Server can read the delegation chain
contents. In cross-domain deployments, JWE encryption or the
chain-by-reference pattern (see below) should be used to
prevent downstream domains from reading upstream delegation
records.¶
Deployments should determine the minimum amount of
information necessary for delegation validation and include
only such claims in delegation records. The
operation_summary field should contain only the
minimum text necessary for authorization decisions. The
delegated_policy should be scoped to the specific
operations being delegated. Agent identifiers
(delegator_id, delegatee_id) can be
pseudonymous WIT or SPIFFE URIs rather than human-readable
names, as described in Section 6.3.1 of the OAuth Assertion
Framework ([RFC7521]).¶
Additionally, implementations may use the
delegation_chain_ref pattern (described in
Section 10.7) to replace the inline chain with
an opaque URI, retrieving the full chain via introspection
([RFC7662]) over a TLS-protected channel.
The RECOMMENDED short token lifetime (5 to 15 minutes,
see Section 10.6) limits the exposure window of
any leaked delegation records.¶
Delegated tokens are subject to replay and theft attacks. The following mitigations address both threats.¶
Sender-constrained tokens: Implementations SHOULD bind issued access tokens to the delegatee's key material using one of the following mechanisms:¶
jkt thumbprint matches the key binding in
the access token.¶
delegatee_id in the
delegation record.¶
When sender-constrained tokens are not used, the
delegatee_id field alone provides only
application-level binding. Deployments that accept this
weaker binding SHOULD compensate with shorter token
lifetimes and network-level controls.¶
Delegation request replay: An attacker replays a captured Token Exchange request to the AS to obtain a new delegated token. Mitigations include:¶
subject_token's
iat claim (RECOMMENDED skew: 5 minutes);¶
OAuth-Client-Attestation) ensure that a
replayed request from a different endpoint fails
client authentication at the AS;¶
Token replay and theft: An attacker presents a stolen delegated token to a Resource Server. Mitigations include:¶
delegatee_id of the most
recent delegation record (index 0);¶
Implementations SHOULD use sender-constrained tokens for
both the delegation request and the issued delegated
token, especially in multi-hop chains where a stolen
token could grant access across multiple trust
boundaries. The delegation_chain claim
additionally enables post-incident forensic analysis by
identifying the agents and timestamps at each hop.¶
Implementations SHOULD enforce maximum delegation depth to:¶
A RECOMMENDED default maximum depth is 5 hops.¶
When a delegation request would exceed the configured maximum
depth, the AS MUST reject the request with an OAuth 2.0 error
response using the error code
delegation_depth_exceeded and a
human-readable error_description indicating the
maximum delegation depth has been reached. If a Resource
Server receives a token whose delegation_chain length
exceeds its locally configured maximum depth, it SHOULD reject
the request regardless of signature validity, as excessively
deep chains may indicate a misconfigured or malicious
delegation path.¶
Implementers should consider the impact of delegation chain depth on token size. Each delegation record typically adds 500 to 1000 bytes to the token payload, including one or two JWS signatures (approximately 200 bytes each for ES256) and, when present, the structured policy content. A 5-hop delegation chain may therefore add 2.5 to 5 KB to the access token. This can cause issues with:¶
To mitigate token size growth, implementations MAY use one or more of the following strategies:¶
delegation_chain on demand;¶
delegation_chain in the JWT, issue a
compact token carrying only a delegation_chain_ref
(a URI pointing to the full chain stored at the AS). The
Resource Server retrieves the chain via introspection or a
dedicated endpoint. This approach keeps the token payload
constant regardless of chain depth, at the cost of an
additional round-trip for chain retrieval;¶
delegated_policy field rather than the full policy
content.¶
When delegation chains span multiple trust domains, additional security considerations apply:¶
as_signature on delegation records issued
by Authorization Servers in other trust domains. Each
delegation record carries an as_id field that
identifies the AS that created it, enabling the Resource
Server to select the correct public key for signature
verification. When delegation records cross a domain
boundary, the receiving AS preserves the upstream records
with their original as_id and
as_signature values intact. To obtain the
public key for a given as_id, the Resource
Server uses Authorization Server Metadata
([RFC8414]), a shared trust framework, or
deployment-specific key exchange. When the receiving AS
adds new delegation records to the chain, it signs them
with its own signing key and sets as_id to its
own identifier. Cross-domain key trust relationships may
be established through key exchange agreements, published
JWKS endpoints ([RFC8414]), or a shared
trust framework.
Failure to properly verify cross-domain AS signatures
may allow forged delegation records to be accepted.¶
sub, scope, and policy identifiers may have
different semantics across trust domains. Implementations MUST
ensure that claim interpretation is consistent or explicitly
mapped at each domain boundary, following the claims transcription
guidance in [I-D.ietf-oauth-identity-chaining].¶
Revocation of delegated authorization is a critical security operation. This section defines the revocation semantics for delegation chains.¶
Revocation Scopes:¶
delegation_chain), all downstream delegated tokens
derived from that root authorization MUST be considered
invalid. Resource Servers validating a delegation chain MUST
verify that the root authorization remains valid, either by
checking the root token's status directly or by using token
introspection ([RFC7662]) on the root token.¶
Revocation Detection Mechanisms: Resource Servers and downstream Authorization Servers MUST implement at least one of the following mechanisms to detect delegation revocation:¶
In addition to the privacy considerations outlined in
[RFC8693] and [RFC7519], the following
privacy considerations apply to the delegation_chain
mechanism defined in this specification.¶
The delegation_chain claim carries identity and
authorization information about the original user, all
intermediate agents, and the delegation policies. As the chain
grows with each hop, the amount of information embedded in the
token increases. Implementations should apply data minimization
principles:¶
operation_summary field is OPTIONAL and should
contain only the minimum information necessary for
authorization decisions, not detailed descriptions of user
intent or behavior.¶
delegated_policy should be scoped to the specific
operations being delegated, not include broader context about
the user's overall authorization.¶
delegator_id,
delegatee_id) should be pseudonymous where possible,
avoiding direct exposure of personally identifiable
information.¶
When delegation chains cross trust domain boundaries, the
delegation_chain claim propagates user and agent
identity information from the originating domain to downstream
domains. This creates the following privacy risks:¶
sub claim reveals the original user's identity in
the originating domain to all downstream domains. Implementations
should consider identifier mapping or pairwise pseudonymous
identifiers, following the claims transcription guidance in
[I-D.ietf-oauth-identity-chaining].¶
evidence claim may contain details about the user's
consent interaction (e.g., displayed content, session context,
channel). Downstream domains receive this information. ASes
should minimize the evidence payload or apply domain-specific
filtering before cross-domain propagation.¶
When the Delegation Interaction Phase is triggered (as described in Section 5), the user is presented with delegation details for review and approval. Implementations should ensure that the consent UI clearly communicates:¶
This specification registers the following claim in the "JSON Web Token Claims" registry:¶
This specification registers the following parameters in the "OAuth Parameters" registry established by [RFC6749] Section 11.2:¶
The interaction_callback_uri parameter is used in
the delegation Token Exchange request context
(Section 5.2) to receive a
redirect callback upon completion of user interaction. A
similar parameter for the JWT Authorization Grant
(grant_type=jwt-bearer) is described in
[I-D.parecki-oauth-jwt-grant-interaction-response].
This specification registers the parameter for use with the
Token Exchange grant type
(grant_type=token-exchange).¶
This specification registers the following error codes in the "OAuth Extensions Error Registry" established by [RFC6749] Section 11.4:¶
invalid_grant error defined in
[RFC6749] addresses general grant
validation failures.
invalid_delegation_chain (this specification)
specifically addresses delegation chain validation
failures such as broken continuity, invalid signatures,
or expired timestamps.¶
invalid_grant error defined in
[RFC6749] addresses general grant
validation failures.
delegation_depth_exceeded (this specification)
specifically addresses the case where the delegation chain
would exceed the AS's configured maximum depth.¶
invalid_scope error defined in
[RFC6749] addresses scope validation
failures.
policy_expansion_detected (this specification)
specifically addresses the case where the requested
delegated_policy or scope is broader
than the delegator's authorized policy.¶
The following shows an extended token held by Agent C after two delegation hops (User → Agent A → Agent B → Agent C), using WIT-based identifiers, structured policies, and authorization evidence:¶
{
"iss": "https://as.example.com",
"sub": "user_12345",
"aud": "https://api.shop.example",
"exp": 1734520500,
"iat": 1734517800,
"act": {
"sub": "wit://agent-c.example/sha256.ccc333..."
},
"delegation_chain": [
{
"delegator_id": "wit://agent-b.example/sha256.bbb222...",
"delegatee_id": "wit://agent-c.example/sha256.ccc333...",
"as_id": "https://as.example.com",
"delegation_timestamp": 1734517800,
"root_evidence_ref": "urn:uuid:a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"delegated_policy": {
"type": "rego",
"content": "package agent\ndefault allow = false\n\nallow if {\n input.action == \"inventory_check\"\n input.item_id == \"123\"\n}",
"entry_point": "allow"
},
"operation_summary": "Check stock for item 123",
"delegator_signature": "eyJhbGciOiJFUzI1NiJ9..MEYCIQD2...",
"as_signature": "eyJhbGciOiJSUzI1NiJ9..MEUCIQDy..."
},
{
"delegator_id": "wit://agent-a.example/sha256.aaa111...",
"delegatee_id": "wit://agent-b.example/sha256.bbb222...",
"as_id": "https://as.example.com",
"delegation_timestamp": 1734516900,
"root_evidence_ref": "urn:uuid:a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"delegated_policy": {
"type": "rego",
"content": "package agent\ndefault allow = false\n\nallow if {\n input.action == \"cart_op\"\n}\nallow if {\n input.action == \"inventory_op\"\n}",
"entry_point": "allow"
},
"operation_summary": "Delegate inventory operations",
"delegator_signature": "eyJhbGciOiJFUzI1NiJ9..MEYCIQD1...",
"as_signature": "eyJhbGciOiJSUzI1NiJ9..MEUCIQDx..."
}
],
"evidence": {
"id": "urn:uuid:a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"user_confirmation": {
"displayed_content": "Allow shopping assistant to manage cart",
"user_action": "button_click",
"timestamp": 1734516000
},
"as_signature": "eyJhbGciOiJFUzI1NiJ9..MEUCIQDw..."
}
}
This token shows:¶
A scope-based equivalent of the same scenario
would omit the delegated_policy,
delegator_signature, root_evidence_ref,
evidence fields. Each
delegation record would carry only delegator_id,
delegatee_id, as_id,
delegation_timestamp, operation_summary, and
as_signature. The token's scope claim alone
would express the progressively narrowing authorization
(e.g., cart:read inventory:read → inventory:read
→ inventory:read:item:123).¶
This appendix provides a condensed checklist for implementers. The normative requirements are specified in Section 9 and Section 10; this checklist is informative only.¶
Each delegation hop is represented as a separate JWT access token
issued and signed by the Authorization Server. The delegating
agent MAY additionally provide a delegator_signature
within the delegation_chain record for dual-signature
non-repudiation (RECOMMENDED).¶
Token structure (per hop):¶
iss: Authorization Server identifier¶
sub: original user (preserved from root)¶
act.sub: delegatee agent identifier¶
delegation_chain: accumulated delegation records¶
Resource Server validation steps:¶
iss¶
as_signature on each delegation record, when
present, using the key of the AS identified by the record's
as_id (SHOULD; in single-domain deployments the
token-level signature suffices)¶
delegator_signature when present (SHOULD)¶
record[i].delegatee_id == record[i-1].delegator_id¶
act.sub == record[0].delegatee_id¶
delegated_policy present (SHOULD)¶
Per-hop signing benefits: independent non-repudiation per delegator, flexible per-hop revocation, incremental chain updates, and discrete audit events.¶