| Internet-Draft | OAuth Actor Profile | April 2026 |
| McGuinness | Expires 19 October 2026 | [Page] |
OAuth deployments increasingly involve multi-principal scenarios where an agent or workload acts on behalf of a human user across organizational and trust-domain boundaries. Existing specifications provide relevant building blocks but do not define a common profile for representing the delegated actor relationship across token types, classifying actor entity types, or signaling support between authorization servers and resource servers. The result is inconsistent actor representation and interoperability gaps that force deployments to rely on proprietary conventions.¶
This document defines the OAuth Actor Profile for Delegation. The design center is delegation clarity: client_id identifies the OAuth client registration, sub identifies the authorizing principal, and act.sub identifies the actor exercising that authorization. These are distinct concepts that this profile makes explicit in the token rather than leaving them to be inferred from client registration context. The profile defines a common act claim structure with sub_profile for machine-processable entity classification, applies existing top-level cnf sender-constraint mechanisms consistently across JWT assertion grants, JWT access tokens, and Transaction Tokens, and specifies processing rules for authorization servers and resource servers. It also defines how supporting Token Exchange inputs such as ID tokens, refresh tokens, JWT actor credentials, and the may_act claim are processed when introducing subject or actor identity into that three-token actor-profile model. The document also registers metadata parameters for advertising actor-profile support and partial capability signals in cross-domain deployments. This document standardizes the token representation of delegation relationships and the processing rules for issuers and consumers; it does not standardize the upstream policies and mechanisms by which systems determine whether a given actor is authorized to act for a subject, which remain deployment-specific.¶
This note is to be removed before publishing as an RFC.¶
The latest revision of this draft can be found at https://mcguinness.github.io/draft-mcguinness-oauth-actor-profile/draft-mcguinness-oauth-actor-profile.html. Status information for this document may be found at https://datatracker.ietf.org/doc/draft-mcguinness-oauth-actor-profile/.¶
Discussion of this document takes place on the Web Authorization Protocol Working Group mailing list (mailto:oauth@ietf.org), which is archived at https://mailarchive.ietf.org/arch/browse/oauth/. Subscribe at https://www.ietf.org/mailman/listinfo/oauth/.¶
Source for this draft and an issue tracker can be found at https://github.com/mcguinness/draft-mcguinness-oauth-actor-profile.¶
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 19 October 2026.¶
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.¶
When an agent acts on behalf of a user across trust domains, every system in the path needs to know who authorized the request and who is making it. Existing specifications provide relevant building blocks ([RFC8693] introduced the act claim for token exchange) but do not define a consistent, interoperable way to represent delegated actor relationships across JWT assertion grants, JWT access tokens, and Transaction Tokens, nor how common Token Exchange input credentials should feed that representation.¶
Several interoperability gaps result from the absence of such a profile. The sub claim is routinely overloaded to represent heterogeneous entity types (end users, service accounts, AI agents, and workloads) without a standard classification mechanism, preventing deterministic cross-domain policy evaluation. Actor context, including key material associated with the acting party, has no standard representation that survives token transformation, as JWT assertion grants, JWT access tokens, and Transaction Tokens are specified in separate documents with differing claim conventions. Many deployments address actor representation through implicit delegation, inferring the acting party from the OAuth client identity (client_id or azp); this approach does not generalize to deployments where a single client registration fronts multiple agents, where requests pass through intermediary services, or where tokens cross organizational trust boundaries, because the client registration does not uniquely identify the runtime actor in those cases. Finally, neither AS metadata [RFC8414] nor Protected Resource Metadata [RFC9728] define parameters for advertising actor-profile support, requiring bilateral out-of-band configuration that does not scale to environments where clients dynamically discover services across trust domains.¶
The design center of this document is delegation clarity. client_id identifies the OAuth client registration, sub identifies the authorizing principal, and act.sub identifies the actor exercising that authorization. These are distinct concepts. This profile makes the actor explicit in the token rather than leaving it to be inferred from client registration context, and it does so without redefining client identity or top-level subject semantics.¶
This document addresses that gap by specifying:¶
A common actor profile structure that reuses act from [RFC8693] and adds sub_profile for entity-type classification.¶
Processing rules for profiled token families and supporting Token Exchange inputs, including how actor-profile information is validated and preserved across supported token transformations.¶
Resource-server guidance for evaluating delegated access using the (sub, outermost act.sub) pair.¶
Integration with OAuth Entity Profiles and discovery metadata so actor classification and capability signaling can be used consistently across deployments.¶
The mechanisms are general-purpose and apply beyond AI agent scenarios. This document is a profile and extension of existing OAuth building blocks; unless stated otherwise, the requirements of [RFC8693], [RFC9068], [RFC9449], and [I-D.ietf-oauth-transaction-tokens] continue to apply.¶
Alice authorizes an AI agent to book a business trip on her behalf, and the request crosses from the enterprise identity provider's domain into an external booking domain and then into the booking provider's internal service mesh. The enterprise authorization server first issues a delegated credential that keeps Alice as sub and the agent as act; downstream issuers later transform that credential into an access token and, for the internal tool hop, a Transaction Token rebound to the booking tool as the new presenter. Across those steps, the subject remains Alice, the immediate actor changes only when a new presenter is explicitly established, and each trust-domain boundary re-issues the token under local control. Appendix B provides the full end-to-end walkthrough.¶
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, as shown here.¶
Unless otherwise specified, OAuth terms such as client, authorization server, resource server, access token, refresh token, grant, Transaction Token, and Transaction Token Service (TTS) are used as defined in [RFC6749], [RFC8693], [I-D.ietf-oauth-transaction-tokens], and related specifications.¶
The following terms are used in this document:¶
The party that is actively making a request. When delegation is present, the actor is distinct from the subject; the subject is the principal on whose behalf the actor is acting.¶
The principal whose authorization is being exercised. In a delegated token, the subject is the original authorizing party (e.g., an end-user or an upstream service), not the party making the immediate network request.¶
The act by which a principal authorizes another party (the actor) to exercise a subset of the principal's rights.¶
A delegation scenario in which the subject and actor are governed by different trust domains or different identifier-namespace authorities under deployment policy. This document does not define a universal interoperable algorithm for classifying a particular token instance as cross-domain. Deployments typically make that determination from issuer context, identifier-namespace authority, and the applicable trust framework or bilateral agreement. The token's top-level iss alone is not sufficient to make that determination in all deployments.¶
An authorization policy evaluation that considers both the subject and the actor, and the relationship between them, as policy inputs. Under this profile, the relevant actor is ordinarily the outermost actor.¶
The act object at the top level of the delegation chain (the one not nested inside any other act object). When a delegation chain of depth greater than one is present, the outermost actor identifies the immediate bearer of the token.¶
Deployment-specific rules, configurations, or decisions made by an individual AS, RS, or organization that are not specified by this document. Local policy MAY include delegation approval rules, scope-reduction algorithms, actor-identifier namespace mappings, and entity-profile acceptance criteria. When this document references local policy, the specific decision logic is intentionally not standardized.¶
Two identifiers or claims are semantically consistent when they refer to the same logical entity under an explicit trusted local mapping rule applicable to the context in which they appear. When this document states that an AS or RS MUST verify semantic consistency between two identifiers, the AS or RS MUST apply its configured mapping rules to determine whether the identifiers are known to refer to the same entity. String similarity, shared naming patterns, or deployment intuition are not sufficient. Absent an applicable explicit mapping rule, the identifiers MUST be treated as distinct.¶
Examples in this document are illustrative and focus on actor-profile-related claims and processing. They may omit unrelated claims, parameters, or validation steps required by the underlying specifications for a complete deployment.¶
This profile specifies an extended form of the act claim defined in [RFC8693]. When an implementation elects to use this profile in a context where an actor is distinct from the subject, it MUST apply the profile as defined in this section. This document standardizes actor-profile claim structure, processing rules, and discovery metadata. It does not standardize delegation approval policy, trust framework decisions, or identifier-mapping logic; those remain deployment-specific. The absence of an explicit actor-carrying inbound credential MUST NOT be interpreted as meaning that the OAuth client automatically defines the delegated actor.¶
The following invariants define the interoperable core of this profile:¶
sub is the authorizing principal.¶
The outermost act.sub is the immediate actor for the current token presentation.¶
act.iss identifies namespace authority for act.sub; it is not a credential-issuer claim or hop-provenance marker.¶
Nested act objects are preserved prior-actor context unless a deployment explicitly applies additional local-policy processing to them; this profile does not standardize authorization semantics for those nested entries.¶
client_id and azp are OAuth client identifiers, not actor identifiers.¶
This profile does not standardize the following:¶
delegation approval, consent, or grant-management policy¶
subject-identifier translation mechanisms or proof of subject equivalence across namespaces¶
authorization semantics for nested act objects¶
client discovery or preflight algorithms beyond the metadata semantics defined here¶
cross-domain trust frameworks for establishing namespace authority for act.iss¶
SAML 1.1 or SAML 2.0 assertions as Token Exchange subject_token inputs; while [RFC8693] defines token type URNs for SAML assertions, actor-profile extraction from XML-based SAML credentials is outside the scope of this document¶
Conformance to this profile means that issuers and consumers represent, preserve, validate, and interpret actor claims consistently according to this document. It does not require every deployment to enforce authorization of the (sub, outermost act.sub) pair on every request, although such enforcement is RECOMMENDED for security-sensitive delegated access.¶
Same-domain deployments will often satisfy these requirements with straightforward local configuration for namespace authority and identifier mapping. Cross-domain deployments typically require explicit trust-framework or bilateral agreement decisions and therefore have a higher interoperability burden under this profile.¶
This profile defines actor-profile requirements for JWT assertion grants, JWT-formatted access tokens, and Transaction Tokens. It does not define an equivalent interoperable profile for opaque access tokens. Deployments using opaque access tokens, including as subject_token or actor_token inputs to Token Exchange, are out of scope for this document. An AS MAY translate introspection results for an opaque access token into equivalent local inputs for deployment-specific use, but that behavior is not interoperable behavior defined by this document.¶
The actor profile defines processing rules for the following token types as issued outputs: JWT assertion grants (Section 4), JWT-formatted access tokens (Section 5), and Transaction Tokens (Section 7.1). It also defines Token Exchange input processing for JWT assertion grants, JWT access tokens, OpenID Connect ID tokens, refresh tokens, and Transaction Tokens as subject_token, and for workload identity credentials, JWT client assertions, and JWT access tokens as actor_token. The may_act pre-authorization claim (Section 6.1.6) applies to any JWT used as subject_token.¶
Subject to endpoint policy and the underlying token-exchange or grant mechanism, implementations MAY transform a supported input token type into a supported output token type for which this document defines the relevant issuance processing. This document normatively defines JWT assertion grant issuance (Section 6.3.1), JWT access token issuance via Section 6.3.2 after authorization-grant processing, Token Exchange processing, or Transaction Token Service processing, and Transaction Token issuance from inbound JWT assertion grants, JWT access tokens, or Transaction Tokens under Section 7.4. It does not require every implementation to support every possible cross-product of supported inputs and outputs. When an implementation supports a path defined by this document, actor profile information MUST be preserved and validated as specified for the resulting token type.¶
This document profiles token contents and the processing of those contents once present. It does not redefine the request semantics of [RFC8693], including the syntax or baseline meaning of subject_token, actor_token, resource, audience, or requested_token_type. When such inputs carry or imply actor information, this document defines only how that information is represented in issued tokens and how issuers and consumers process it.¶
For worked examples showing the actor profile in use in both same-domain service delegation and cross-domain delegation, see Appendix A and Appendix B.¶
The following table summarizes the minimum implementation obligations by role. The "Detailed rules" column contains forward references to the normative sections where each role's requirements are fully defined; readers using this table as a quick-reference checklist may follow those links directly.¶
| Role | Inputs | Minimum checks | Outputs / behavior | Detailed rules |
|---|---|---|---|---|
| Assertion-consuming AS | JWT assertion grant with act
|
Validate JWT; trust issuer; validate delegation when required by the applicable processing path or local policy; enforce chain-depth limit | Preserve actor in issued token | Section 4.2 |
| Token-exchange AS (subject_token) | ID token, JWT assertion grant, JWT access token, refresh token, or Transaction Token as subject_token
|
Validate per credential type; trust issuer; validate delegation when required by local policy; enforce scope reduction and chain-depth limit | Issue token with preserved or extended act chain |
Section 6.1.4.2, Section 6.1.1, Section 6.1.2, Section 6.1.5.2, Section 6.1.3; then Section 6.3.2 |
| Token-exchange AS (actor_token) | Workload identity credential, JWT client assertion, or JWT access token as actor_token
|
Validate per credential type; trust issuer; verify proof of possession; derive outermost actor identity | Construct outermost act from validated actor identity; then apply Section 6.3.2
|
Section 6.2.2.2, Section 6.2.1, Section 6.2.3 |
| Resource Server | Access token or Transaction Token carrying act
|
Validate token; validate presenter binding; evaluate subject; evaluate (sub, outermost act.sub) pair when required by local policy |
Apply delegated-token policy; advertise actor_authorization_required when enforcing (sub, outermost act.sub) authorization |
Section 9.3, Section 9.4 |
| Transaction Token Service | JWT assertion grant, JWT access token, or Transaction Token with subject and optional act chain |
Validate inbound actor information; preserve subject identity; enforce chain-depth limit; apply presenter authentication per Transaction Token mechanism | Preserve sub; treat req_wl as supporting context; add new outermost act
|
Section 7.4 |
| Client or Agent | AS and RS metadata | Check entity_profiles_supported.actor and actor_profile_token_types_supported when available |
Detect likely capability mismatch | Section 10.2 |
An actor object is a JSON object that is the value of the act claim. In addition to the sub claim required by [RFC8693], an actor object MUST contain an iss claim, SHOULD contain a sub_profile claim, and MAY contain a cnf claim.¶
act-object = {
"sub" : StringOrURI, ; REQUIRED
"iss" : StringOrURI, ; REQUIRED
? "sub_profile" : JSON String, ; RECOMMENDED
? "cnf" : cnf-object, ; OPTIONAL
* StringOrURI => any ; extension claims
}
¶
sub:REQUIRED. The subject identifier of the actor, as defined in [RFC8693], Section 4.1. This value identifies the acting party. It is a StringOrURI as defined in [RFC7519]. When the (act.iss, act.sub) pair identifies the same entity as the (iss, sub) pair of the token (that is, when the actor and subject are the same party under the same namespace authority), no delegation is expressed; including an act claim is typically not useful in that case. When act is present but identifies the same entity as sub, consumers MUST NOT infer a meaningful delegation relationship from the token. String equality of act.sub and sub alone is not a sufficient test; the namespace authority (act.iss vs. token iss) must also be considered.¶
iss:REQUIRED. Identifies the namespace authority for the actor identifier carried in act.sub, playing the same role for act.sub that the JWT iss claim plays for the token sub: just as iss + sub form a globally unique principal identifier in a JWT (see [RFC9493]), act.iss + act.sub form a globally unique actor identifier within the delegation chain. For URI, client, workload, or other deployment-specific identifiers, the value of act.iss MUST identify the authority that the deployment treats as authoritative for resolving or validating that actor identifier. See "Cross-Domain Delegation" in Section 2. The value is a StringOrURI as defined in [RFC7519].¶
Unlike the credential issuer, which is an AS-internal concern resolved during assertion validation, act.iss identifies only the namespace authority and is not a credential-issuer claim or hop-provenance marker. The namespace authority and the credential issuer may be the same entity or different entities. In many deployments the value is an HTTPS URL, but other well-known identifier schemes (for example, a URN for workload identities) are also possible. Preserving an inner act object in a newly issued token does not change the meaning of its act.iss value and does not cause that inner entry to become independently authenticated by the new issuer; it remains prior-actor information carried within the outer issuer's trust context.¶
For example, a TTS might issue a Transaction Token with top-level iss equal to https://tts.travel-provider.example while setting act.iss for the booking tool to https://as.travel-provider.example, if local policy treats that AS as authoritative for the booking tool identifier namespace.¶
sub_profile:RECOMMENDED. A space-delimited list of entity profile values classifying the actor identified by act.sub, as defined in Section 4.2 of [I-D.mora-oauth-entity-profiles]. Values used within act objects MUST be registered with the "Actor Profile" usage location in the OAuth Entity Profiles registry (Section 14.1 of [I-D.mora-oauth-entity-profiles]) or be privately defined collision-resistant values. If the acting entity fits more than one profile, multiple values MAY be included as a space-delimited string (e.g., "service ai_agent"). Policy evaluation rules for multi-value strings are defined in Section 3.7.¶
Per-actor key provenance within the delegation chain is outside the scope of this profile. The current presenter's keying material is conveyed only by the token's top-level cnf claim, as described in Section 3.10. Other members carried inside an act object, including any confirmation-style members defined by another profile, do not have standardized proof-of-possession semantics under this document unless another specification explicitly defines them.¶
The client_profile claim defined in [I-D.mora-oauth-entity-profiles] classifies the OAuth client and MUST NOT appear within an act object. Client classification belongs at the top level of the token. An AS or RS that encounters a client_profile member inside an act node MAY reject the token or ignore the offending member; it MUST NOT treat it as a valid actor classification.¶
When an act object contains extension members beyond those defined in this document, issuers and consumers MUST ignore unrecognized members unless another specification or local policy defines their meaning. An issuer that re-issues a validated actor chain MAY preserve unrecognized extension members in inherited act objects under local policy.¶
sub_profile Policy Evaluation
Value preservation and propagation for unrecognized sub_profile values are governed by [I-D.mora-oauth-entity-profiles]. An AS or RS MUST NOT reject a token or assertion solely because a sub_profile value is unrecognized; unrecognized values MUST NOT be used to infer authorization semantics.¶
The sub_profile claim improves local policy expression and coarse compatibility signaling, but it does not make authorization outcomes portable across deployments. Two deployments can accept the same sub_profile value while applying different authorization consequences to it.¶
When local policy restricts the accepted set of sub_profile values for an actor, that set SHOULD be advertised via entity_profiles_supported.actor in AS metadata (Section 10.2.2) so that clients can detect incompatibility before making a request. Clients discover the accepted set for a given resource by consulting entity_profiles_supported.actor in the AS metadata for the AS listed in the resource's authorization_servers ([RFC9728]).¶
When sub_profile is absent from an act object, implementations MUST NOT assume a specific entity type for the actor. Resource servers that enforce entity-type-based access control MUST treat an absent sub_profile as an unclassified actor and SHOULD apply the more restrictive policy applicable to unknown entity types.¶
When sub_profile contains multiple space-delimited values, the following guidance applies to policy evaluation:¶
As a safe default, an entity can be treated as matching a policy rule if any of its sub_profile values satisfies that rule. For example, an entity with "service ai_agent" matches both a policy rule for service and a policy rule for ai_agent.¶
When multiple values match different policy rules with conflicting outcomes, implementations are encouraged to apply the more restrictive outcome rather than the union of all matched rules' privileges. The specific conflict resolution logic is a local policy decision; this document recommends least privilege across the matched set as a safe default.¶
When local policy accepts only a specific set of sub_profile values (e.g., via entity_profiles_supported.actor), the entity can be accepted if at least one of its values appears in the accepted set. Values not in the accepted set SHOULD be ignored for that acceptance check; they do not by themselves require rejection.¶
Delegation chains MUST be represented by nesting act objects as specified in [RFC8693], Section 4.1. In a nested structure, the outermost act object identifies the immediate actor; inner act objects represent prior actors in the chain, with the innermost representing the original delegating party. This structure records delegated-actor history within the trust model of the issuer that conveys it; it does not, by itself, provide independent cryptographic provenance for each prior hop.¶
This document uses the following terminology consistently:¶
A single-hop actor object is an act object with no nested act; it represents delegation depth 1.¶
An inbound actor chain is the complete act structure received in an inbound token, whether depth 1 or greater.¶
A preserved actor chain is an inbound actor chain that an issuer has validated and copied into a newly issued token without rewriting inherited actor entries.¶
A new outermost actor is the actor object created by the current issuer to represent the newly identified outermost actor for the token it is issuing.¶
{
"sub": "https://idp.enterprise.example/users/alice",
"sub_profile": "user",
"act": {
"sub": "https://tools.example.com/booking-tool",
"iss": "https://as.travel-provider.example",
"sub_profile": "service",
"act": {
"sub": "https://agents.example.com/travel-assistant",
"iss": "https://as.enterprise.example",
"sub_profile": "ai_agent"
}
}
}
¶
In this example the booking tool (outermost act) is the current outermost actor. The delegation chain originates with Alice (sub), who first authorized the travel assistant (nested act); the travel assistant then sub-delegated to the booking tool, which is now the immediate presenter. The chain carries prior-actor information to the extent that the current token issuer is trusted to have validated and faithfully propagated it.¶
Delegation depth is defined as the number of act objects in the chain, counting from the outermost. A token with a single act object and no nested act within it has depth 1. Each additional level of nesting adds 1. Depth is counted on the resulting chain after any new outermost act is added, not on the inbound token. Implementations MUST support at least one level of delegation (depth 1). Implementations intended for cross-domain multi-hop interoperability SHOULD support at least five levels of nested act objects to accommodate realistic multi-tier architectures (e.g., user → orchestrator → agent → tool → internal service). An implementation that supports only depth 1 and rejects all depth-2 or deeper chains is conformant to this document but will not interoperate with multi-hop deployments. Same-domain deployments MAY support a shallower local maximum when that limit is sufficient for their architecture. Implementations MAY support larger depths and SHOULD define and enforce a local maximum delegation depth according to deployment needs. Implementations that receive a token exceeding their configured local maximum delegation depth MUST reject it with invalid_request. When a request would result in a chain that exceeds that local limit, the AS MUST reject the request with invalid_request; it MUST NOT silently truncate the chain.¶
The following normative algorithm governs how an AS validates an inbound actor chain and constructs the actor chain in the issued token. It applies to all token types defined in this profile. Type-specific sections in Section 4.2, Section 6, and Section 7.4 reference this algorithm and add type-specific preconditions. This algorithm governs claim handling only; it does not by itself create new delegation-authorization requirements beyond those imposed by the applicable processing section and local policy.¶
Depth of an actor chain: the number of nested act objects counted from the outermost. A single act object with no nested act has depth 1; each additional nesting level adds 1. Depth is measured on the chain as it appears in the issued token, after any new outermost actor is added.¶
Security-relevant entry: an inner act object that local policy uses as an additional input to issuance decisions (authorization, scope determination, or identity mapping). Use of such entries is deployment-specific and outside the baseline interoperable behavior of this profile.¶
Prior-actor context: an inner act object preserved for audit or downstream authorization purposes without being used as a direct input to the current issuance decision.¶
V1 — Validate outer token. The AS MUST validate the token carrying the inbound actor chain per the type-specific rules applicable to that token before extracting actor claims.¶
V2 — Validate outermost actor. For the outermost act object the AS MUST:¶
Verify that both act.sub and act.iss are present. If either is absent, reject with invalid_request.¶
Verify that act.iss is authoritative for the identifier namespace of act.sub, per Section 4.2 step 3. If not, reject with invalid_grant.¶
When the applicable processing path or local policy requires confirmation of the (sub, act.sub) delegation relationship, evaluate whether act.sub is authorized to act on behalf of sub per local delegation policy (Section 4.2 step 4). If policy explicitly prohibits it, reject with access_denied. If such confirmation is required and the delegation relationship cannot be confirmed from current inputs, reject with actor_unauthorized.¶
V3 — Optional local validation of inner actors. Interoperable processing under this profile is defined around sub and the outermost act.sub. If local policy additionally uses an inner act object as an input to issuance decisions, the AS SHOULD apply the same three sub-steps as V2 for that entry, including delegation-confirmation only when the current processing path or local policy requires it for that entry. Such use of inner actors is deployment-specific.¶
V4 — Carry prior-actor context. For inner act objects preserved solely as prior-actor context without being used for any issuance decision, the AS MAY rely on trust in the outer token issuer established in V1 rather than independently validating each hop. The AS MUST NOT treat preserved prior-actor context as independently authenticated.¶
V5 — Enforce depth limit. Compute the depth of the resulting chain, including any new outermost actor added per C1. If that depth exceeds the locally configured maximum (Section 3.8), reject with invalid_request.¶
C1 — Add new outermost actor (when a new actor is identified).¶
AddOutermostActor(inbound_chain, new_actor):
outermost.sub = new_actor.sub // REQUIRED
outermost.iss = new_actor.iss // REQUIRED: namespace authority for new_actor.sub
outermost.sub_profile = new_actor.sub_profile // RECOMMENDED when known
if inbound_chain is present:
outermost.act = inbound_chain // nest entire validated inbound chain
verify depth(outermost) <= local_max_depth // per V5
return outermost
¶
The act.iss value in the new outermost actor MUST be set by the issuing AS. The AS MUST NOT rewrite act.iss or any other field in inherited inner actor objects; those fields were set by upstream issuers at the time of authorship and are immutable.¶
No flattening. Dropping prior actors from the inbound chain to produce a shallower chain in the issued token is NOT permitted. If preserving the inbound chain would cause the resulting depth to exceed the local maximum, the AS MUST reject with invalid_request rather than silently truncate. The only exception is when the inbound token carries no act claim, in which case no prior chain exists and the issued token begins a new chain at depth 1.¶
C2 — Preserve inbound chain unchanged (when no new actor is identified).¶
PreserveChain(inbound_chain): return inbound_chain // copy without modification¶
The AS MUST copy the validated inbound chain exactly into the issued token. The AS MUST NOT add, remove, or rewrite any field in any actor object of a preserved chain.¶
C3 — No act in issued token. When no delegation is present and no actor information should appear in the issued token, the AS MUST NOT include an act claim. The AS MUST NOT silently drop an inbound act claim; if it cannot preserve or extend the chain, it MUST reject the request per Section 8.1.¶
When Agent A (the inbound outermost actor) triggers a request that establishes Agent B as the new outermost actor:¶
Apply C1: Agent B becomes the new outermost actor; the entire inbound chain — including Agent A — is nested beneath Agent B.¶
The result is sub=U, act={B.sub, B.iss, act={A.sub, A.iss}}, not sub=U, act={B.sub, B.iss} (which would silently drop Agent A from the chain).¶
If Agent B and Agent A have the same identifier under the same namespace authority (that is, they are the same party), the AS MAY apply C2 — preserving the existing chain unchanged — rather than adding a redundant nesting.¶
When sender-constrained tokens are used with a delegated token, the top-level cnf claim identifies the key or certificate of the immediate presenter of that token. When delegation is present, that immediate presenter is ordinarily the party identified by the outermost actor. Authorization servers and resource servers validate current proof of possession against the top-level cnf.¶
When a sender-constrained token is used only as an inbound credential in Token Exchange, its top-level cnf remains binding information for that inbound token instance. If the exchange keeps the same presenter, the requester proves possession of that key per the underlying sender-constraint mechanism. If the exchange legitimately introduces a distinct new presenter established by an actor_token or by the output-token mechanism (for example, Transaction Token issuance that re-binds the delegation chain to a new presenter), the AS validates the current requester's proof under the credential or mechanism that establishes that new presenter and MUST NOT require the new presenter to prove possession of the prior presenter's key solely because the inbound subject_token was sender-constrained.¶
The top-level cnf.jkt of the token MUST identify the key of the immediate presenter, the actor identified by the outermost act claim.¶
This profile does not define per-actor confirmation members within nested act objects. Stronger prior-hop key provenance, if needed, would require another profile layered on top of this one.¶
When mTLS ([RFC8705]) is used instead of DPoP, the top-level cnf.x5t#S256 identifies the current presenter's certificate.¶
The following normative rules govern proof-of-possession (PoP) validation for all token types and credential exchanges defined in this profile. Individual processing sections reference these rules and MUST apply them in addition to any type-specific requirements stated there.¶
cnf Governs the Current Presenter
The top-level cnf claim of any token identifies the key or certificate of the current presenter. The AS or RS MUST validate proof of possession against the top-level cnf. Confirmation-style members that appear inside an act object due to another specification do not have standardized proof-of-possession semantics under this document.¶
When a JWT assertion grant is sender-constrained with DPoP ([RFC9449]):¶
The assertion MUST carry a top-level cnf.jkt identifying the DPoP key to which the assertion is bound. If cnf.jkt is absent, the AS MUST reject with invalid_request.¶
The AS MUST verify the DPoP proof against the cnf.jkt value in the assertion, not against the presenter's locally registered key.¶
In cross-domain flows where cnf.jkt was set by an upstream issuer, the AS SHOULD treat the inbound cnf.jkt as the expected key and SHOULD reject with invalid_grant if the DPoP proof does not match, unless another sender-constraint profile or explicit local binding rule defines a different continuity model.
### Actor Tokens Carrying cnf.jkt¶
When an actor_token of any credential type carries cnf.jkt:¶
The request MUST include valid proof for the key identified by cnf.jkt using the mechanism applicable to that actor_token profile and deployment (for example, DPoP for a DPoP-bound JWT credential or a WPT for a WIMSE workload credential). If the required proof is absent or invalid, the AS MUST reject with invalid_grant.¶
When DPoP is the applicable proof mechanism, the request MUST include a valid DPoP proof over the token endpoint URI for the key identified by cnf.jkt.¶
If a sender-constrained subject_token is also present and local policy requires the same presenter to continue across the exchange, the proof key established for the actor_token and the subject_token's cnf.jkt MUST identify that same presenter.¶
When a sender-constrained subject_token carrying cnf.jkt is presented in a Token Exchange:¶
Same presenter: The requester MUST prove possession of the key identified by the subject_token's cnf.jkt. If the proof is absent or invalid, the AS MUST reject with invalid_grant.¶
New presenter: When the request establishes a distinct new presenter via actor_token or the output-token mechanism, the subject_token's cnf.jkt is binding information for that prior token instance only. The AS MUST validate the current requester's proof under the credential or mechanism that establishes the new presenter and MUST NOT reject solely because the new presenter's key differs from the subject_token's cnf.jkt.¶
This rule applies across all subject_token types (JWT assertion grants, JWT access tokens, Transaction Tokens, ID tokens, and refresh tokens).¶
The act object structure defined in Section 3.6 applies uniformly to all three token types covered by this document. The following tables summarize claim requirements.¶
The sub-claims of the act object have the same requirement level regardless of which token type carries the act claim:¶
| Claim | Requirement | Definition |
|---|---|---|
act.sub
|
REQUIRED when an act claim is present |
Section 3.6 |
act.iss
|
REQUIRED | Section 3.6 |
act.sub_profile
|
RECOMMENDED | Section 3.6 |
Requirements for top-level claims vary by token type:¶
| Claim | JWT Assertion Grant | JWT Access Token | Transaction Token |
|---|---|---|---|
act
|
REQUIRED when delegation is asserted | REQUIRED when delegated | REQUIRED when delegated |
sub_profile
|
RECOMMENDED | RECOMMENDED | propagated from inbound subject token |
cnf
|
REQUIRED when DPoP is used; otherwise OPTIONAL | REQUIRED when sender-constrained | Per deployment; binds the current presenter when used |
req_wl
|
not applicable | not applicable | REQUIRED |
The sub_profile claim MAY also appear as a top-level JWT claim (outside any act object) to classify the entity type of the token's sub. Its value MUST be a space-delimited entity profile string per [I-D.mora-oauth-entity-profiles] and applies exclusively to sub; it does not affect sub_profile values within act objects. Issuers SHOULD include a top-level sub_profile when they can authoritatively classify the subject entity type.¶
Detailed token definitions and processing rules are defined in Section 4, Section 5, Section 6, and Section 7.4.¶
This chapter defines the actor-profile structure and authorization-grant processing rules for JWT assertion grants. JWT access-token structure, Token Exchange processing, and Transaction Token Service processing are defined in later chapters.¶
Actor-profile requirements apply to any JWT used as an authorization grant under [RFC7521] and [RFC7523], independent of how or by which specification it was produced. One such profile is the Identity Assertion JWT Authorization Grant (ID-JAG, [I-D.ietf-oauth-identity-assertion-authz-grant]), a JWT bearer grant produced by Token Exchange.¶
Such a JWT MAY include an act claim conforming to the actor profile defined in Section 3. Use of this claim in JWT client authentication assertions is out of scope for this document because such assertions have different issuer and subject semantics. However, implementers should note that some deployments rely on the authenticated OAuth client itself as implicit evidence of the acting party. This specification does not prohibit that input, but when delegation is to be expressed explicitly and propagated across token transformations, the acting party is represented by act rather than inferred solely from client authentication.¶
The following claims are defined for a JWT assertion grant that carries actor-profile delegation. Claims not listed here follow the requirements of [RFC7521] and [RFC7523].¶
iss (REQUIRED):Identifies the assertion issuer. MUST be authorized by local policy to assert the relationship between sub and act.sub.¶
sub (REQUIRED):The principal on whose behalf the grant is being made.¶
sub_profile (RECOMMENDED):Classifies the entity type of sub. MUST conform to the values defined in Section 3.¶
act (REQUIRED when delegation is asserted):The actor object identifying the entity exercising the subject's delegated rights. MUST conform to the actor object structure defined in Section 3. MUST include act.sub and act.iss.¶
cnf.jkt (REQUIRED when DPoP is used; otherwise OPTIONAL):When the JWT assertion grant is sender-constrained with DPoP, the assertion MUST carry a top-level cnf.jkt identifying the DPoP key to which the assertion is bound. When DPoP is not used, top-level cnf is OPTIONAL for JWT assertion grants unless required by another profile or local policy.¶
When the assertion or request context also identifies an OAuth client via client_id, azp, or an authenticated client credential, interoperable processing SHOULD use act.sub rather than treating that client identity as a substitute for it. Deployments that rely on client identity as a substitute actor signal are outside the interoperable scope of this profile; see step 7 in Section 4.2.¶
Clients SHOULD use JWT assertion grants carrying actor-profile claims only when the AS's support for the actor-determination model has been confirmed via deployment documentation, prior agreement, or discovery.¶
The following example shows an AS-issued assertion grant, which is the recommended pattern. The Enterprise IdP AS performed Token Exchange, authenticated the agent as the OAuth client, established the delegation relationship under local policy, and signed the assertion. act.iss equals the token iss here because the enterprise AS is also the namespace authority for the agent's identifier:¶
{
"iss": "https://as.enterprise.example",
"sub": "https://idp.enterprise.example/users/alice",
"aud": "https://as.resource-domain.example/token",
"jti": "a1b2c3d4-...",
"exp": 1711820400,
"iat": 1711816800,
"sub_profile": "user",
"cnf": { "jkt": "NzbLsXh8uDCcd7MNwrnNZpX0ak8ACQ" },
"act": {
"sub": "https://agents.enterprise.example/travel-assistant",
"iss": "https://as.enterprise.example",
"sub_profile": "ai_agent"
}
}
¶
The top-level sub_profile classifies the JWT's sub; sub_profile within act classifies the actor. The top-level cnf.jkt binds the assertion to the agent's DPoP key.¶
The AS-issued grant is the more trustworthy pattern because the issuing AS independently authenticated the agent and validated the delegation relationship before signing. The receiving AS needs to trust only the enterprise AS as an issuer.¶
For AS-issued grants, the issuing AS MUST set act.iss to the namespace it is authoritative for, typically its own issuer URI.¶
Allowed issuer patterns are:¶
an AS-issued delegated assertion where JWT iss is a trusted AS and act.sub identifies the actor (recommended),¶
an assertion carrying a pre-existing nested act chain where the current JWT iss is trusted to carry forward prior actor assertions, and¶
a self-issued actor assertion (see Section 4.1.1 below).¶
In a self-issued assertion grant, the agent itself is iss and directly asserts Alice's delegation to itself in act.sub. No upstream AS has authenticated the agent or pre-validated the delegation relationship.¶
{
"iss": "https://agents.enterprise.example/travel-assistant",
"sub": "https://idp.enterprise.example/users/alice",
"aud": "https://as.resource-domain.example/token",
"jti": "a1b2c3d4-...",
"exp": 1711820400,
"iat": 1711816800,
"sub_profile": "user",
"act": {
"sub": "https://agents.enterprise.example/travel-assistant",
"iss": "https://as.enterprise.example",
"sub_profile": "ai_agent"
}
}
¶
Here act.iss names the enterprise AS as the namespace authority for the agent's identifier, which is registered in that AS's namespace rather than the agent's own identifier space. The client MUST set act.iss to the issuer namespace authoritative for its own identifier, typically the AS governing the namespace in which act.sub is registered; the client MUST NOT set act.iss to its own identifier unless it is itself the authoritative namespace owner.¶
ASes MUST NOT accept self-issued assertion grants unless explicitly configured via local policy to do so; self-issued grant acceptance MUST be off by default. When an AS does accept self-issued grants, it MUST at minimum:¶
Validate the JWT signature using the key identified in the JWT header, obtained from a trusted source (e.g., a pre-registered public key for the self-issuing party).¶
Reject assertions whose jti has already been accepted within the assertion's validity window to prevent replay.¶
Verify proof of possession per the token-endpoint mechanism in use (DPoP per [RFC9449] or mTLS per [RFC8705]).¶
Apply the actor-profile validation requirements of this specification (steps 2–7 of Section 4.2).¶
The AS SHOULD NOT treat the self-asserted delegation claim alone as a sufficient basis under step 4 of Section 4.2; an independent delegation basis such as a pre-registered grant or consent record is RECOMMENDED. Any additional verification of the claimed sub is a deployment-specific subject-identity matter outside the scope of this document. This document does not define any additional self-issued-proof mechanism beyond those listed above.¶
When an AS receives a JWT assertion grant containing an act claim:¶
The AS MUST determine that the assertion issuer is trusted to assert the relationship between the JWT sub and act.sub. In the typical case the JWT iss is a trusted AS, and the AS MUST verify that this issuer is authorized under local policy to assert delegation on behalf of the actor identified by act.sub. For self-issued grants, see Section 4.1.1.¶
If act.iss is absent from the inbound act object, the AS MUST reject the request with invalid_request; an absent act.iss is a structural violation, not a validation failure. Otherwise, the AS MUST establish, under a trusted framework or local policy, that act.iss is authoritative for the identifier namespace of act.sub. This step validates namespace authority only; it does not reinterpret act.iss as a credential-issuer claim or as proof that every upstream hop was independently authenticated. This document does not define a single interoperable algorithm for making that determination. Deployments MAY rely on federation metadata, pre-registration, bilateral agreements, deployment-specific policy, or another equivalent trust mechanism. Cross-domain interoperability for act.iss validation is only well-defined when the participating parties share such a trust framework or explicit agreement. If the AS cannot establish that act.iss is authoritative for the namespace containing act.sub, the AS MUST reject the request with invalid_grant. Section 11.3 provides non-normative examples of local validation approaches.¶
Before issuing a token, the AS SHOULD evaluate whether act.sub is authorized to exercise delegation on behalf of sub, using the AS's local policy (for example, a pre-registered delegation grant, an explicit consent record, or a policy rule covering the acting party). When AS policy explicitly prohibits the identified actor from acting on behalf of the subject, the AS MUST return access_denied. The form of delegation authorization is not standardized by this profile.¶
If the inbound assertion's act object contains a nested act claim (indicating that the asserted actor is itself a delegatee), the AS MUST handle the inner chain as follows:¶
Propagation decision: The AS MUST determine whether to propagate the inner chain into the issued token. The AS SHOULD propagate it by preserving the nested structure, provided the total resulting chain depth does not exceed the limit in Section 3.8. If the AS does not accept pre-chained assertions, it MUST reject the request.¶
Entries used by the AS for issuance decisions: Interoperable processing is defined around sub and the outermost act.sub. If local policy additionally uses an inner act object for authorization, scope determination, or another issuance decision, the AS SHOULD validate the act.sub and act.iss pair per step 3 and SHOULD evaluate the delegation relationship per step 4. Such use of inner act objects is deployment-specific rather than part of the baseline interoperable behavior of this profile.¶
Preserved prior-actor context: For inner act objects the AS preserves only as prior-actor context, the AS MAY rely on trust in the outer assertion issuer per step 2 rather than independently validating each prior hop. Under this profile, preserved inner act objects are not part of the baseline interoperable authorization input; downstream authorization interoperability is defined around sub and the outermost act.sub.¶
No implicit authentication: The AS MUST NOT treat any preserved inner actor as independently authenticated merely because it appears in the re-issued token, and preserving such an entry does not by itself endorse it for downstream access-control use.¶
The AS MUST verify proof of possession per the token-endpoint mechanism in use (DPoP per [RFC9449] or mTLS per [RFC8705]).¶
DPoP: The inbound assertion grant MUST carry a top-level cnf.jkt. The AS MUST verify the DPoP proof against that value rather than the presenter's locally registered key. In cross-domain flows the cnf.jkt was set by the upstream issuer; the AS SHOULD treat it as the expected key and SHOULD reject with invalid_request if it is absent or invalid_grant if the proof does not match, unless another sender-constraint profile or explicit local binding rule defines a different continuity model.
> Note: The absence of confirmation members inside act does not affect the DPoP binding obligation; [RFC9449] requires the AS to bind the issued token's top-level cnf.jkt to the DPoP proof key regardless.¶
If the assertion or authenticated request context identifies an OAuth client separately from act.sub:¶
The AS MAY use that client identity as an additional authorization input.¶
The AS SHOULD NOT infer that the client is authorized to act on behalf of the subject solely because the client initiated the request. Such inference is outside the interoperable behavior defined by this profile.¶
When local policy maps the client identity to an actor identifier expected to match act.sub, the AS SHOULD validate semantic consistency before issuing a token. If that consistency cannot be established, the AS MUST either treat the identifiers as distinct or reject the request according to local policy.¶
If the AS accepts the assertion, it MUST propagate the actor information into the issued token according to the rules for the output token type being issued. For JWT access tokens, see Section 6.3.2. For Transaction Tokens, see Section 7.4. When the output is another JWT assertion grant profile, the resulting assertion MUST preserve the validated actor information subject to local policy and the chain-depth limit in Section 3.8.¶
The AS MAY add additional sub_profile or act metadata to the issued token based on its own knowledge of the principals.¶
This chapter defines the actor-profile structure of delegated JWT access tokens used by this document. Processing rules that lead to issuance of such tokens are defined in the applicable processing chapters.¶
A delegated JWT access token is a JWT access token per [RFC9068] that carries an act claim conforming to the actor profile defined in Section 3. Claims not listed here follow [RFC9068] and any other applicable token profile.¶
The following claims are defined for a JWT access token that carries actor-profile delegation:¶
iss (REQUIRED):Identifies the access token issuer.¶
sub (REQUIRED):Identifies the principal on whose behalf the access token is issued.¶
sub_profile (RECOMMENDED):Classifies the entity type of sub. MUST conform to the values defined in Section 3.¶
act (REQUIRED when the token represents delegation):The actor object identifying the entity exercising the subject's delegated rights. MUST conform to the actor object structure defined in Section 3. MUST include act.sub and act.iss. When the token does not represent delegation, act MUST be omitted.¶
cnf (REQUIRED when sender-constrained; otherwise OPTIONAL):Binds the access token to the current presenter when a sender-constraining mechanism such as DPoP or mTLS is used.¶
client_id and azp (OPTIONAL):Identify the OAuth client when carried in the token. They do not identify the delegated actor and MUST NOT be used as a substitute for act.¶
Some deployments also carry an azp claim as an auxiliary client-identity signal, often as an OpenID Connect carry-over used by vendors in practice. When an issuer uses both azp and act.sub to represent the same acting party, it SHOULD ensure they are semantically consistent or else treat them as distinct identifiers under local policy. Deployments that rely on client identity claims as a substitute for act are outside the interoperable scope of this profile. For migration and reconciliation rules, see Section 11.4 and Section 12.2.¶
The following example shows a JWT access token with actor profile claims:¶
{
"iss": "https://as.resource-domain.example",
"sub": "https://idp.enterprise.example/users/alice",
"client_id": "travel-assistant-client-id",
"azp": "https://agents.example.com/travel-assistant",
"aud": "https://api.resource-domain.example",
"jti": "xyz987",
"exp": 1711820400,
"iat": 1711816800,
"scope": "travel:book",
"sub_profile": "user",
"cnf": {
"jkt": "NzbLsXh8uDCcd7MNwrnNZpX0ak8ACQ"
},
"act": {
"sub": "https://agents.example.com/travel-assistant",
"iss": "https://as.enterprise.example",
"sub_profile": "ai_agent"
}
}
¶
In this single-hop case the top-level bearer key identifies the same party as the outermost actor because the actor is the bearer. The differing client_id, azp, and act.sub values in this example are intentional: they illustrate a deployment where client-facing identifiers and actor identifiers are distinct and must be reconciled, if at all, only through trusted local mapping rules. In multi-hop chains each actor remains a distinct identity in the chain; see Appendix B.¶
When an AS issues a JWT access token outside Token Exchange and intends the token to represent delegation, it MUST establish an independent delegation basis for the (sub, actor) relationship. Examples include a pre-registered delegation grant, an explicit consent record, or a policy rule covering the acting party or a class of acting parties.¶
A client registration MAY satisfy this requirement only when it uniquely identifies a single distinct acting entity and the AS can derive that actor's identifier from the registration alone (for example, a dedicated registration for a specific agent or service). A client registration that fronts multiple distinct acting entities (for example, an agent orchestration platform or shared-client deployment) does NOT satisfy this requirement, because client_id alone does not identify the runtime actor in those cases.¶
When the AS determines the actor from authenticated client context, local delegation policy, or other deployment-specific inputs rather than from an explicit actor-carrying artifact, that is an operational allowance rather than an interoperable actor-proof mechanism defined by this document. The interoperability defined here applies to the issued token and its processing, not to the upstream method by which the AS determined the actor.¶
The authorization code flow is within scope of the preceding rules. When a resource owner interactively authorizes an agent via /authorize, the AS MAY include act in the issued access token if it has an independent delegation basis establishing that the OAuth client is acting as a distinct actor on behalf of the resource owner. The actor identity MUST be derived from that delegation basis. If no such basis exists, the AS MUST NOT include act in the access token.¶
Each credential type presented as subject_token or actor_token in a Token Exchange request is processed per the applicable rules in this chapter. These rules explain how subject or actor identity is introduced into the actor-profile model; they do not redefine the core act semantics in Section 3.¶
This chapter covers RFC 8693 Token Exchange input processing and the output-token issuance rules for JWT assertion grants and JWT access tokens. JWT assertion-grant structure is defined in Section 4.1. JWT access-token structure is defined in Section 5.1. Transaction Token issuance is defined separately in Section 7.¶
Authorization-server error handling for requests processed in this chapter is defined in Section 8.1.¶
This profile defines three JWT-based actor_token credential types. JWT access tokens use actor_token_type=urn:ietf:params:oauth:token-type:access_token (Section 6.2.3). RFC 7523 client assertions (Section 6.2.1) and workload identity credentials (Section 6.2.2.2) both use actor_token_type=urn:ietf:params:oauth:token-type:jwt and are distinguished by accompanying request parameters and deployment configuration. In practice, a JWT presented as both actor_token and client_assertion with client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer is identified as the RFC 7523 client-assertion profile. If the AS cannot identify exactly one supported actor-credential profile for the actor_token, it MUST reject the request with invalid_grant.¶
JWT assertion grants are not suitable for use as actor_token in Token Exchange. Their sub identifies the subject of delegation rather than the acting party. Requests that need to establish an agent, workload, or client as the actor SHOULD use one of the actor credential types defined in this chapter instead.¶
When a Token Exchange request ([RFC8693]) presents a JWT assertion grant as the subject_token, the AS MUST apply the validation rules of Section 4.2 (steps 1 through 7) to validate the inbound token. Steps 8 and 9 of that section do not apply; propagation and scope reduction are governed by the rules below and by Section 6.3.2.¶
If the inbound assertion grant carries cnf.jkt and the exchange keeps the same presenter for the resulting token, the requester MUST present a valid DPoP proof over the token endpoint URI for that key. If the request instead establishes a distinct new presenter by actor_token or by the output-token mechanism, the inbound assertion grant's cnf.jkt remains binding information for the prior token instance only. In that case the AS MUST validate the current requester's proof per the credential or mechanism that establishes the new presenter and MUST NOT reject solely because the new presenter's key differs from the inbound assertion's cnf.jkt.¶
The AS MUST apply scope reduction per [RFC8693], Section 4 and MUST then apply the propagation rules in Section 6.3.2.¶
When a Token Exchange request ([RFC8693]) presents a JWT access token as the subject_token (subject_token_type=urn:ietf:params:oauth:token-type:access_token), the AS MUST apply the following steps. Use of an opaque access token as the subject_token is outside the interoperable scope of this profile. An AS MAY translate introspection results for an opaque access token into equivalent local inputs for deployment-specific use, but that behavior is not interoperable behavior defined by this document.¶
The AS MUST validate the inbound JWT access token per [RFC9068]: signature, iss, exp, and nbf. Because a JWT access token used as subject_token was issued for a resource server, its aud will not ordinarily include the Token Exchange AS's token endpoint; the AS MUST NOT reject the inbound token solely because its aud does not include the AS's token endpoint URI.¶
The AS MUST verify that the inbound token's iss is trusted under local policy to assert the delegation chain it carries. If not, the AS MUST reject the request with invalid_grant.¶
If the inbound token carries cnf.jkt, the AS MUST handle presenter continuity as follows.¶
Same presenter: The requester MUST include a valid DPoP proof ([RFC9449]) over the token endpoint URI for that key.¶
New presenter: If the request establishes a distinct new presenter through an actor_token or the output-token mechanism, the inbound token's cnf.jkt remains binding information for the prior token instance only. The AS MUST validate the current requester's proof under the credential or mechanism that establishes the new presenter and MUST NOT reject solely because that proof uses a different key.¶
The AS MUST extract sub, sub_profile (if present), and act (if present) from the validated token as the inbound delegation state for Section 6.3.2.¶
The AS MUST apply scope reduction per [RFC8693], Section 4. The effective scope of the issued token MUST NOT exceed the inbound token's effective scope.¶
After completing these steps, the AS MUST apply the propagation rules in Section 6.3.2.¶
When a Token Exchange request ([RFC8693]) presents a Transaction Token as the subject_token (subject_token_type=urn:ietf:params:oauth:token-type:txn_token) to a regular AS (not a TTS), the AS MUST apply the following steps.¶
The AS MUST validate the Transaction Token per [I-D.ietf-oauth-transaction-tokens]: signature, aud, exp, and iat, and it MUST establish the token issuer identity. When the inbound Transaction Token carries an act claim, the top-level iss claim MUST be present; if it is absent, the AS MUST reject the request with invalid_request. When iss is present, the AS MUST validate it as the Transaction Token issuer identifier. When iss is absent and the token carries no act claim, the AS MUST determine the issuer using the trust-domain and issuer-identification rules of [I-D.ietf-oauth-transaction-tokens] and local deployment configuration. If validation fails or the issuer identity cannot be established, the AS MUST reject the request with invalid_grant.¶
The AS MUST verify that the Transaction Token issuer identified in step 1 is trusted under local policy. If not, the AS MUST reject the request with invalid_grant.¶
When the inbound Transaction Token carries a top-level presenter-binding claim such as cnf, the AS MUST validate the accompanying proof per [I-D.ietf-oauth-transaction-tokens] and the applicable deployment profile.¶
Same presenter: The requester MUST prove possession of the bound key or credential.¶
New presenter: If the request establishes a distinct new presenter via actor_token or the output-token mechanism, the inbound binding applies to the prior token instance only. The AS MUST validate the current requester's proof under the credential or mechanism that establishes the new presenter and MUST NOT reject solely because the new presenter does not possess the prior key.¶
If the AS relies on continuity of the prior presenter and the required proof cannot be established, it MUST reject the request with invalid_grant.¶
The AS MUST extract sub, sub_profile (if present), and act (if present) from the validated Transaction Token as the inbound delegation state for Section 6.3.2.¶
The req_wl claim identifies the workload that requested the Transaction Token from the TTS and provides informational context about the transaction origin. The AS MAY use req_wl for audit or local policy decisions but MUST NOT carry it forward into the issued JWT access token.¶
The AS MUST apply the propagation rules in Section 6.3.2. For a Transaction Token used as subject_token, this document defines only the actor-profile consequences of the inbound sub, act, req_wl, and presenter-binding state. Transaction Token field semantics and any transaction-specific scope handling remain defined by [I-D.ietf-oauth-transaction-tokens], [RFC8693], and local policy.¶
An OpenID Connect ID token [OpenID.Core] is a JWT issued by an OpenID Provider (OP) that asserts the authenticated identity of a user. Its sub identifies the user, its aud identifies the relying party (the OAuth client) to which it was issued, and it may carry azp as an authorized-party/client identifier per [OpenID.Core]. Under this profile, aud and azp remain client-identity inputs; they do not establish actor identity. ID tokens carry no act claim and no delegation chain; they establish the user's identity only.¶
In this profile, ID tokens serve as subject_token in Token Exchange requests to introduce a user identity into a delegation chain. The acting party is established by the actor_token. This is the foundational pattern for cross-domain identity chaining: the user's OIDC identity flows forward as sub in the issued token while the actor identity becomes act.sub.¶
When a Token Exchange request ([RFC8693]) presents an ID token as the subject_token (subject_token_type=urn:ietf:params:oauth:token-type:id_token), the AS MUST apply the following steps.¶
The AS MUST validate the ID token per [OpenID.Core] and local policy before using it as actor-profile input. Any checks on aud or azp remain OpenID Connect and client-identity checks; they do not by themselves establish the delegated actor under this profile.¶
The AS MUST use the validated ID token's sub as the subject identity for the issued token, subject to the same-subject preservation rule in Section 6.3.2 step 2.¶
The AS SHOULD set sub_profile to user in the issued token if it can authoritatively classify the ID token's sub as a human user identity and no conflicting subject classification is available under local policy.¶
The ID token does not establish actor identity. If an actor_token is present, the AS MUST process it per its type-specific rules and MUST use the derived actor identity as act.sub. If no actor_token or independent delegation basis is present, the AS MUST NOT include act in the issued token.¶
The AS MUST apply the propagation rules in Section 6.3.2 to determine the remaining claims in the issued token. Because an ID token carries no inbound act chain and no OAuth scope ceiling, actor-chain construction and scope determination come from the actor_token (if any), [RFC8693], and local policy rather than from the ID token itself.¶
A refresh token is a long-lived credential issued by an AS to a specific OAuth client that authorizes that client to obtain new access tokens without repeating end-user authentication. Refresh tokens are opaque by design; they do not carry claims such as sub or act and are validated through the issuing AS's own token store rather than by signature verification.¶
Refresh tokens MAY be presented as subject_token in a Token Exchange request to introduce a user's existing authorization into a delegation chain; for example, when an agent that holds a user's refresh token needs a delegated access token for a specific resource. Because refresh tokens carry no identity claims directly, the actor MUST be established by an actor_token in the same request or by an independent delegation basis under local policy.¶
Refresh tokens MUST NOT be used as actor_token. They carry no actor identity, are opaque credentials bound to a user authorization grant rather than to a workload or client identity, and cannot supply the sub value required to construct act.sub.¶
This document does not standardize client-binding policy, cross-client presentation policy, or cross-AS acceptance policy for refresh tokens used as subject_token. Those behaviors remain deployment-specific.¶
When a Token Exchange request ([RFC8693]) presents a refresh token as the subject_token (subject_token_type=urn:ietf:params:oauth:token-type:refresh_token), the AS MUST apply the following steps.¶
The AS MUST validate the refresh token through its own token store or a trusted back-channel with the issuing AS. Signature-based validation does not apply. If the token is expired, revoked, or otherwise invalid, the AS MUST reject the request with invalid_grant.¶
The AS MUST extract the subject identity and authorized scope associated with the refresh token from its token store or other trusted refresh-token state. The sub of the user associated with the refresh token becomes sub in the issued token. The AS SHOULD set sub_profile in the issued token if it can authoritatively classify the subject entity type.¶
Refresh tokens carry no act claim; the acting party MUST be established by an actor_token or an independent delegation basis under local policy. If neither is present, the AS MUST NOT include act in the issued token. If an actor_token is present, the AS MUST process it per its type-specific rules and MUST use the actor identity derived by those rules as the outermost actor in the issued token. In particular, when the actor_token is a delegated JWT access token, the AS MUST use the outermost act.sub and act.iss derived under Section 6.2.3 rather than the actor_token's top-level sub.¶
The effective scope of the issued token MUST be a subset of the scope authorized by the refresh token. The AS MUST apply scope reduction per [RFC8693], Section 4 against that ceiling.¶
After completing steps 1-4, the AS MUST apply the propagation rules in Section 6.3.2 to determine the remaining claims in the issued token.¶
The may_act claim ([RFC8693], Section 4.4) is defined for JWTs and token introspection responses. When a JWT subject_token carries may_act in a Token Exchange request, the claim is a single JSON object identifying one authorized actor for the subject identified by the containing JWT. The object contains identity claims for that authorized actor; it is similar in purpose to act but is not constrained to have exactly the same member set. For this profile's delegation-authorization shortcut, sub is the minimum identity member and iss is required for baseline interoperable matching unless the authoritative namespace for that sub is established unambiguously by the containing token or trusted local policy. When present in a JWT subject_token, may_act allows the AS to satisfy its delegation-authorization requirement from information embedded in the subject token, without requiring an independent policy lookup. The delegation-authorization check is defined by the type-specific processing section for the subject_token type in use (e.g., step 4 of Section 4.2 for JWT assertion grants).¶
may_act is an input to Token Exchange processing and MUST NOT be propagated into the issued token.¶
When the AS processes a Token Exchange request whose JWT subject_token carries a may_act claim, the AS MUST apply the following rules.¶
The AS MUST validate the subject_token per its type-specific rules before evaluating may_act. A may_act claim in an invalid or untrusted token MUST NOT be used.¶
The AS MUST compare the actor identity it is prepared to use for the issued token against the identity claims in may_act. For this profile, the candidate actor identity is the (act.iss, act.sub) pair that would appear in the issued token if the request succeeds. When an actor_token is present, that candidate identity is the actor_token's derived actor identity. When no actor_token is present, the AS MAY derive a candidate actor identity from the authenticated client's identity only if local policy defines an explicit trusted mapping from that client identity to both the actor identifier and its authoritative namespace; absent such a mapping, the authenticated client identity MUST NOT be treated as a substitute for act.sub.¶
If may_act contains both sub and iss, the AS MUST compare that pair to the candidate (act.iss, act.sub) pair using exact equality or trusted local semantic-consistency rules.¶
If may_act contains sub but omits iss, the AS MUST NOT treat may_act as a sufficient basis for delegation authorization unless the containing token issuer or trusted local policy unambiguously establishes the authoritative namespace for that sub.¶
If may_act omits sub, the AS MUST NOT use it as a sufficient basis for delegation authorization.¶
Other members in may_act MAY refine local policy but do not define additional interoperable identity-matching inputs under this profile.¶
If the resulting issuer-scoped actor identity matches the party identified by may_act, the AS MAY treat that match as a sufficient basis for its delegation-authorization requirement for the subject_token type in use, subject to local policy.¶
When both may_act and an actor_token are present, the following rules govern their interaction:¶
A matching may_act MAY satisfy the delegation-authorization requirement but does not supply or override the actor identity. The actor_token remains the authoritative source for act.sub in the issued token.¶
The AS MUST NOT use a matching may_act to replace the actor_token's derived identity in the issued token's act.sub.¶
When may_act identifies a different party than the actor_token's derived identity, the AS MUST use the actor_token's derived identity as act.sub and MUST fall back to its independent delegation-authorization policy per step 5. A non-matching may_act is not itself grounds for rejection.¶
A may_act match does not override other validation requirements. The AS MUST still validate the actor_token, verify issuer trust, and enforce proof of possession per the applicable type-specific section. When client identity is used under step 2 via trusted mapping, the AS MUST apply the same semantic-consistency rules described in Section 4.2 step 7 and Section 12.2.¶
The AS MUST NOT carry may_act forward into the issued token. The claim is consumed during Token Exchange processing and MUST NOT appear in any output token type defined by this profile.¶
When may_act is present but the actor's identity does not match the party identified there, the AS MUST fall back to its independent delegation-authorization policy applicable to the subject_token type in use. A non-matching may_act is not itself grounds for rejecting the request.¶
A JWT client assertion ([RFC7521][RFC7523]) may be presented as actor_token to establish an OAuth client's own identity as the acting party. In this usage the request uses actor_token_type=urn:ietf:params:oauth:token-type:jwt, and the JWT has sub equal to the client's own identifier, iss identifying that same client, aud set to the token endpoint, and is signed with the client's private key. Two usage patterns arise:¶
The same JWT is presented as both client_assertion and actor_token in a single request, making the authenticated client identity explicit in the issued token's act chain.¶
The client authenticates by another method (e.g., client_secret, mTLS) and presents a separate JWT client assertion as actor_token to name that same client as the actor.¶
To establish an agent, workload, or other principal distinct from the OAuth client_id as the actor, the request MUST use a different actor credential type, such as a workload identity credential (Section 6.2.2.2), whose sub names that distinct principal. An RFC 7523 client assertion cannot name a subordinate identity while remaining conformant to [RFC7523].¶
When a Token Exchange request includes an actor_token that is a JWT client assertion, the AS MUST apply the following steps.¶
The AS MUST validate the actor_token per [RFC7523]: signature, iss, sub, aud, exp, and jti. The aud MUST be the AS's token endpoint URI, and sub MUST identify the OAuth client itself as required by [RFC7523]. If the same JWT is also used as client_assertion for client authentication in the same request and this shared RFC 7523 validation fails, the AS MUST reject the request with invalid_client per [RFC7523]. Otherwise, if validation fails, the AS MUST reject the request with invalid_grant.¶
The AS MUST verify that the actor_token's iss is a client registered with the AS, that sub equals that client's client_id, and that local policy permits that client's assertion to be used as an actor credential. If not, the AS MUST reject the request with invalid_grant.¶
The actor_token's sub identifies the immediate acting party. The AS MUST use it as act.sub in the outermost act of the issued token and MUST set act.iss to the value authoritative for the namespace containing act.sub.¶
When the actor_token is the same JWT presented as client_assertion for client authentication in the same request, the AS MAY derive the actor identity from the already-authenticated client context rather than re-validating the actor_token separately, provided the result is an identical act.sub value. Actor-profile-specific policy failures that occur after successful client authentication are still invalid_grant, not invalid_client.¶
If the actor_token carries cnf.jkt, the request MUST include a valid DPoP proof ([RFC9449]) over the token endpoint URI for that key. If a sender-constrained subject_token is also present and local policy requires the same presenter to continue across the exchange, the proof key and the subject_token's cnf.jkt MUST identify that same presenter. When the actor_token instead establishes a distinct new presenter for the issued token, differing keys are expected and MUST NOT by themselves cause rejection.¶
When a subject_token is also present and carries an act chain: the actor_token's sub takes precedence as the outermost actor identity; if inconsistent with the outermost actor in the subject_token's chain and local policy does not permit divergence, the AS MUST reject with invalid_grant. Any prior act chain in the actor_token itself MUST NOT be automatically merged with the subject_token's chain; the AS MUST omit it from the issued token unless local policy defines a single unambiguous ordering, in which case the AS MAY preserve it subject to the chain-depth limit in Section 3.8.¶
A workload identity credential is a JWT that asserts the identity of a software workload (such as a microservice, AI agent, or batch job) issued by a workload identity provider. Unlike JWT assertion grants (Section 4.1), whose sub identifies the user or principal on whose behalf the grant is made, a workload identity credential has the workload's own identifier in sub, making it the natural credential type for establishing an agent or service as the acting party in a Token Exchange request. The WIMSE working group defines workload identity credentials in [I-D.ietf-wimse-workload-creds]. Profile disambiguation and actor_token_type assignment are defined in Section 6. This section defines the actor-profile processing rules that apply when such a credential is presented as actor_token.¶
The recommended pattern for agentic Token Exchange is therefore:¶
subject_token: a JWT access token or JWT assertion grant carrying the user's sub and the delegation chain (act)¶
actor_token: a workload identity credential whose sub is the agent or service identity¶
Output: a JWT access token with the user as sub and the workload as the outermost act.sub¶
This pattern ensures that the agent proves its own identity cryptographically while the subject token carries the user's delegated authorization.¶
When a Token Exchange request ([RFC8693]) includes an actor_token that is a workload identity credential, the AS MUST apply the following steps.¶
The AS MUST validate the workload identity credential per its type specification. For WIMSE workload identity credentials ([I-D.ietf-wimse-workload-creds]), validation follows the rules defined in that specification. If validation fails, the AS MUST reject the request with invalid_grant.¶
The AS MUST verify that the workload credential's issuer (iss) is trusted under local policy to assert the workload's identity. If not, the AS MUST reject the request with invalid_grant.¶
The workload credential's sub identifies the immediate acting party. The AS MUST use it as act.sub in the outermost act of the issued token and MUST set act.iss to the value authoritative for the namespace containing act.sub.¶
The AS MUST verify proof of possession for the workload credential. When accompanied by a WIMSE Workload Proof Token (WPT, [I-D.ietf-wimse-wpt]), the AS MUST validate the WPT per that specification. When the credential carries cnf.jkt and a DPoP proof ([RFC9449]) is provided over the token endpoint URI, the AS MUST validate it against that thumbprint. If the required proof is absent or invalid, the AS MUST reject the request with invalid_grant.¶
When a subject_token is also present and carries an act chain:¶
The workload credential's sub takes precedence as the outermost actor identity.¶
If inconsistent with the outermost actor in the subject_token's chain and local policy does not permit divergence, the AS MUST reject with invalid_grant.¶
Any prior act chain in the actor_token itself MUST NOT be automatically merged with the subject_token's chain; the AS MUST omit it from the issued token unless local policy defines a single unambiguous ordering, in which case the AS MAY preserve it subject to the chain-depth limit in Section 3.8.¶
A JWT access token may be presented as actor_token to establish a service or workload as the acting party. When the actor_token is a non-delegated JWT access token (no act claim), its sub identifies the acting party directly. When the actor_token is itself a delegated JWT access token (carries act), the outermost act.sub identifies the acting party; its sub is the principal to whom the token was issued, not the actor.¶
When a Token Exchange request includes an actor_token that is a JWT access token (actor_token_type=urn:ietf:params:oauth:token-type:access_token), the AS MUST apply the following steps. Use of an opaque access token as the actor_token is outside the interoperable scope of this profile; an AS MAY translate introspection results for such tokens into equivalent local inputs, but that behavior is deployment-specific and not defined here.¶
The AS MUST validate the actor_token per [RFC9068]. If validation fails, the AS MUST reject the request with invalid_grant.¶
The AS MUST verify that the actor_token's iss is trusted under local policy to assert the acting party's identity. This trust requirement covers all namespaces from which actor identity will be drawn: when the actor_token does not carry act, the AS MUST verify that iss is trusted to assert sub as the acting party's identifier; when the actor_token carries act, the AS MUST additionally verify that iss is trusted to assert the outermost act.sub namespace. If trust cannot be established for any required namespace, the AS MUST reject the request with invalid_grant.¶
The outermost actor identity is derived from the actor_token based on whether it carries an act claim:¶
If the JWT access token does not carry act, its sub identifies the immediate acting party. The AS MUST use it as act.sub in the outermost act of the issued token and MUST set act.iss to the value authoritative for the namespace containing act.sub.¶
If the JWT access token carries act, it is a delegated token whose sub is the principal to whom it was issued, not the acting party. The AS MUST use the outermost act.sub and corresponding act.iss from the actor_token as the new actor identity. The AS MUST NOT use the actor_token's sub as act.sub. The actor_token's sub and any inner act chain MUST NOT be propagated into the issued token or merged with the subject_token's chain.¶
Note: Step 3 requires the AS to inspect whether the actor_token carries act before determining which claim to extract as the actor identity. Implementations SHOULD log or emit an audit event indicating which path was taken (delegated vs. non-delegated actor_token) to aid in debugging and policy enforcement.¶
If the actor_token carries cnf.jkt, the request MUST include a valid DPoP proof ([RFC9449]) over the token endpoint URI for that key. If a sender-constrained subject_token is also present and local policy requires the same presenter to continue across the exchange, the proof key and the subject_token's cnf.jkt MUST identify that same presenter. When the actor_token instead establishes a distinct new presenter for the issued token, differing keys are expected and MUST NOT by themselves cause rejection.¶
When a subject_token is also present and carries an act chain: the outermost actor identity derived from the actor_token per step 3 takes precedence; if inconsistent with the outermost actor in the subject_token's chain and local policy does not permit divergence, the AS MUST reject with invalid_grant. When the actor_token itself carries act, the actor_token's inner chain MUST NOT be merged with the subject_token's chain.¶
When requested_token_type in a Token Exchange request ([RFC8693]) designates a JWT assertion grant as the output, whether by using urn:ietf:params:oauth:token-type:jwt or a more specific JWT assertion-grant token type defined by another specification (for example, an ID-JAG token type), the issued JWT MUST satisfy the structural requirements of Section 4.1. This section defines the actor-profile requirements for the resulting JWT assertion grant regardless of which compatible JWT assertion-grant output token type was requested. The actor chain MUST be constructed per Section 6.3.2. The aud MUST be set to the downstream token endpoint (from the resource parameter or deployment configuration), and the assertion MUST be signed by the issuing AS. The AS MUST NOT issue a JWT assertion grant as Token Exchange output unless it is configured to do so and can establish the delegation relationship under local policy.¶
The issued JWT access token MUST satisfy the structural requirements in Section 5.1. This section is the common output step for Token Exchange paths in this chapter that produce a JWT access token. It is reached after completing the credential-type-specific subject_token and actor_token processing defined above, or after Transaction Token Service processing.¶
After completing the type-specific validation steps for any subject_token defined in this chapter (Section 6.1.1, Section 6.1.2, Section 6.1.4.2, Section 6.1.5.2, Section 6.1.3) or after Transaction Token Service processing (Section 7.4), the AS MUST apply the following rules when issuing a JWT access token. These rules govern the actor chain, subject, and scope in the issued token regardless of inbound credential type.¶
When both a subject_token carrying an inbound act chain and an actor_token are present, the validated actor_token determines the new outermost actor identity in the issued token. Any preserved inbound act chain from the subject_token is nested beneath that new outermost act; the validation and conflict rules are defined in the applicable actor_token section.¶
If a Token Exchange request explicitly seeks a delegated output, for example by supplying an actor_token or by presenting a subject_token that already carries act, and the AS cannot validate the actor information or cannot establish the required delegation basis, it MUST reject the request with invalid_grant rather than issue a non-delegated JWT access token.¶
When the issued access token represents delegation, the AS MUST include an act claim that preserves or extends the inbound delegation chain per steps 3 and 4. The AS MUST NOT silently drop actor information. If the inbound credential carries no act, no validated actor_token is present, and no independent delegation basis exists, the AS MUST NOT include act in the issued access token.¶
The AS MUST preserve sub to refer to the same underlying subject as the inbound token. If the AS uses a different subject-identifier namespace, it MAY change the sub value only to re-express that same subject in the new namespace under a trusted local mapping. It MUST NOT replace sub with an identifier for a different subject. The mechanics and assurance of subject-identifier translation are deployment-specific and are not otherwise standardized by this document.¶
The AS MUST construct the act claim as follows:¶
Inbound token carries act, new actor identified: The AS MUST nest the existing inbound chain within a new outermost act for the newly identified actor. The new outermost act MUST include act.sub and act.iss for that actor.¶
Inbound token carries act, no new actor: The AS MUST preserve the inbound actor chain unchanged.¶
Inbound token carries no act, new actor identified: The AS MUST create a single-hop outermost act for the newly identified actor. The new act MUST include act.sub and act.iss for that actor.¶
Inbound token carries no act, no new actor: The AS MUST omit act from the issued token.¶
Namespace authority: The act.iss obligation applies only to the act object the AS creates for the current actor. The AS MUST NOT rewrite act.iss or any other field in inherited act objects; those entries were authored by upstream issuers and are fixed at the point of authorship.¶
When the actor identity was derived from an actor_token parameter rather than from an act claim in the subject_token, the outermost act in the issued token is AS-asserted based on the validated actor_token; it is not chain-propagated from the subject token. Consumers MUST NOT infer that the actor_token-derived act was present in or endorsed by the subject token issuer.¶
If actor information that would be preserved or added to the issued token cannot be validated, or nesting would exceed the chain-depth limit in Section 3.8, the AS MUST reject the request. The AS MUST return invalid_request when the chain-depth limit would be exceeded and invalid_grant when actor information fails validation; error codes are as defined in Section 8.1 and apply equally to token exchange requests producing JWT access tokens. The AS MUST NOT issue a token that partially preserves the delegation chain.¶
The AS SHOULD include sub_profile in the issued token's top-level claims if it can authoritatively classify the token's sub entity type.¶
The AS MUST apply scope reduction per [RFC8693], Section 4. If the reduction required by [RFC8693] yields an empty scope, the AS MUST reject the request with invalid_scope.¶
When the AS additionally applies actor-based scope restriction based on the (sub, act.sub) pair or the actor's sub_profile:¶
The AS MUST include the effective scope value in the token response so that clients can detect any reduction from the requested scope.¶
If actor-based restriction yields an empty scope because the actor is categorically unauthorized for any of the remaining scope, the AS MUST reject with actor_unauthorized.¶
Otherwise, if actor-based restriction yields an empty scope, the AS MUST reject with invalid_scope.¶
The scope value in the token response MUST reflect the effective granted scope after all reductions, including any actor-based reduction. This is consistent with the existing requirement in [RFC8693], Section 4 that scope in the response indicate the actual authorized scope. Silent divergence between the requested scope and the issued token's scope is not permitted.¶
If the inbound credential carries client_id, azp, or both, the AS MAY preserve those values per the output token profile or local policy. If preserved:¶
They MUST continue to identify the OAuth client and MUST NOT be rewritten to represent delegation state that belongs in act.¶
If preserving them would create ambiguity about the delegated actor relationship, the AS SHOULD omit them.¶
See Section 12.2 for the normative rules governing client identity and actor identity.¶
Clients SHOULD use the resource parameter ([RFC8707]) when requesting delegated tokens to restrict the issued token's aud claim to the intended resource server. The AS MUST honor resource-indicator constraints in delegated token requests per [RFC8693], Section 4.2. Audience-scoped delegation limits the blast radius of a compromised token by preventing its presentation to resource servers other than the one it was issued for. This profile does not define a new mechanism for audience restriction; it applies the existing resource parameter and aud claim semantics to the delegated-token context.¶
This chapter defines the actor-profile claim structure for Transaction Tokens and the rules a Transaction Token Service (TTS) applies when it validates supported subject_token inputs, authenticates the new presenter, and issues a delegated Transaction Token.¶
TTS error handling for requests processed in this chapter is defined in Section 8.2.¶
Transaction Tokens [I-D.ietf-oauth-transaction-tokens] are short-lived JWTs that capture the workload identity and request context for a series of related service calls within a single business transaction. They are issued by a Transaction Token Service (TTS), which is a specialized authorization server.¶
The Transaction Token claim structure in this section reflects [I-D.ietf-oauth-transaction-tokens] as of the date of this document. If [I-D.ietf-oauth-transaction-tokens] revises any claim listed here, the definition in [I-D.ietf-oauth-transaction-tokens] takes precedence for those claims; the actor-profile-specific requirements in Section 7.1.1 and Section 7.4 remain binding for this profile.¶
A Transaction Token contains the following claims. Claims marked REQUIRED are defined as such by [I-D.ietf-oauth-transaction-tokens]; claims marked OPTIONAL may be omitted at the issuer's discretion.¶
iss (OPTIONAL in [I-D.ietf-oauth-transaction-tokens]; REQUIRED by this profile when carrying act):Issuer of the Transaction Token. MUST be present when the Transaction Token carries an act claim, because act.iss values in the chain are evaluated relative to the token issuer for cross-domain detection and recipients cannot establish namespace authority for act.sub without it. SHOULD be present when the Transaction Token crosses trust-domain boundaries, even in non-delegated cases, as recipients can require it to validate issuer identity or chain-of-trust per local policy. MAY be omitted only when no delegation (act) is present, all tokens are scoped to a single Trust Domain, and all recipients have out-of-band knowledge of the issuer. When iss is omitted, recipients MUST rely on the trust-domain and issuer-identification rules of [I-D.ietf-oauth-transaction-tokens] and local deployment configuration rather than the generic outer-token iss processing rules in this document.¶
aud (REQUIRED):Identifies the Trust Domain in which the Transaction Token is valid.¶
iat (REQUIRED):exp (REQUIRED):sub (REQUIRED):The identity of the human user or non-personal entity that originated the transaction.¶
scope (REQUIRED):The transaction authorization scope, as defined by the TTS for the specific transaction.¶
txn (REQUIRED):A transaction identifier that links all tokens in the same business transaction, as defined in [I-D.ietf-oauth-transaction-tokens].¶
req_wl (REQUIRED):The workload identifier of the workload that requested the Transaction Token from the TTS. When a Transaction Token is exchanged for a replacement, req_wl is updated to reflect the new requesting workload per [I-D.ietf-oauth-transaction-tokens]. This claim provides TTS-level workload context and is not a substitute for act.sub; see Section 7.1.1.¶
tctx (OPTIONAL):Transaction context information that remains stable across the call chain.¶
rctx (OPTIONAL):Request context information. Defined sub-claims are req_ip (originating IP address) and authn (authentication method used).¶
The following table summarizes the claims in a Transaction Token as profiled by this document.¶
| Claim | Status | Actor-profile relevance |
|---|---|---|
iss
|
REQUIRED when carrying act; OPTIONAL otherwise (SHOULD when crossing trust domains) |
Identifies the Transaction Token issuer and, when act is present, provides the outer-token issuer context required by this profile |
aud
|
REQUIRED | Identifies the Trust Domain |
iat
|
REQUIRED | — |
exp
|
REQUIRED | — |
sub
|
REQUIRED | The originating user or entity; MUST be preserved across reissuance |
scope
|
REQUIRED | Transaction authorization scope; not equivalent to OAuth access token scope |
txn
|
REQUIRED | Transaction correlation identifier |
req_wl
|
REQUIRED | Requesting workload context; not a substitute for act.sub
|
act
|
REQUIRED when delegated; OPTIONAL otherwise | Outermost act.sub is the authoritative actor identity for this profile |
cnf
|
Per deployment | Binds the token to the current presenter's key |
tctx
|
OPTIONAL | Stable transaction context |
rctx
|
OPTIONAL | Request context (IP, authn method) |
A Transaction Token is delegated for purposes of this document when it carries an explicit actor credential (either an actor_token in the exchange request or an inbound token that already contains an act chain) establishing that the requesting workload is acting on behalf of the identified sub rather than in its own right. In a delegated Transaction Token, the act claim conforming to this profile MUST be included to represent the current acting party and any prior delegation steps, as specified in Section 7.4. Because a delegated Transaction Token carries act, it MUST also carry a top-level iss claim per Section 7.1. In non-delegated Transaction Tokens (those issued for a workload acting under its own independent grant, where no explicit actor credential was presented), act is OPTIONAL. The TTS MUST NOT infer delegation solely from the fact that sub and req_wl identify different entities; the presence of an explicit actor credential is required.¶
req_wl identifies the workload that requested the token from the TTS. act.sub identifies the immediate acting party in the subject identifier namespace used by this profile. The authoritative actor identifier for authorization decisions under this document is the outermost act.sub; req_wl is supporting workload context.¶
Claim semantics:¶
sub: identifies the original initiator. When a Transaction Token is exchanged for a replacement, the new token MUST continue to refer to the same underlying subject. The issuer MAY change sub only to re-express that same subject in a different identifier namespace.¶
scope: captures the transaction authorization intent for this token instance, per the TTS semantics.¶
req_wl: identifies the workload that requested this token instance from the TTS.¶
act.sub (outermost): identifies the immediate acting party. When req_wl and the outermost act.sub identify the same entity, the issuer SHOULD ensure they are semantically consistent. When a recipient relies on both and cannot reconcile them under local policy, the recipient MUST reject the token.¶
Inner act objects: identify prior presenters in the delegation path. act.sub_profile at each level classifies the entity type of that presenter.¶
The following example shows a Transaction Token after two hops:¶
{
"iss": "https://tts.enterprise.example",
"sub": "https://idp.enterprise.example/users/alice",
"sub_profile": "user",
"scope": "inventory:check",
"req_wl": "https://tools.example.com/booking-tool",
"aud": "https://api.travel-provider.example",
"txn": "550e8400-e29b-41d4-a716-446655440000",
"exp": 1711816900,
"iat": 1711816800,
"tctx": {
"action": "check-availability"
},
"rctx": {
"req_ip": "203.0.113.42"
},
"cnf": {
"jkt": "0ZcOCORZNYy9ZhHiZN..."
},
"act": {
"sub": "https://tools.example.com/booking-tool",
"iss": "https://as.travel-provider.example",
"sub_profile": "service",
"act": {
"sub": "https://agents.example.com/travel-assistant",
"iss": "https://as.enterprise.example",
"sub_profile": "ai_agent"
}
}
}
¶
In this example the booking tool is the current presenter. It is identified by req_wl as the workload that requested the token and by the outermost act.sub in the actor profile's subject namespace, and it has its own top-level cnf.jkt. The travel assistant appears as a nested act object, showing that it was the prior delegated actor between Alice and the booking tool.¶
When the TTS receives a JWT assertion grant as subject_token, it MUST apply the validation, presenter-continuity, and scope-reduction rules in Section 6.1.1. Instead of applying Section 6.3.2, the TTS uses the resulting subject identity, optional sub_profile, inbound act chain, proof-of-possession state, and effective scope ceiling as the inbound delegation state for Section 7.4.¶
When the TTS receives a JWT access token as subject_token, it MUST apply Section 6.1.2 steps 1 through 5. Instead of applying Section 6.3.2, the TTS uses the resulting inbound delegation state as input to Section 7.4.¶
When the TTS receives a Transaction Token as subject_token, it MUST apply Section 6.1.3 steps 1 through 5. Instead of applying Section 6.3.2, the TTS uses the extracted sub, optional sub_profile, inbound act chain, req_wl, and presenter-binding state as input to Section 7.4.¶
When a delegated Transaction Token is issued, the newly authenticated presenter becomes the new outermost actor for that token. Presenter proof is governed by [I-D.ietf-oauth-transaction-tokens] and the applicable deployment profile, while the actor-profile consequences of that presenter change are defined in Section 7.4.¶
When a TTS receives a token-exchange request to issue or refresh a Transaction Token from an inbound JWT assertion grant, JWT access token, or Transaction Token that carries actor-profile claims, it MUST apply the following rules:¶
The TTS MUST preserve sub to refer to the same underlying subject as the inbound token. The TTS MAY change sub only to re-express that same subject in a different identifier namespace under a trusted local mapping. The TTS MUST NOT replace sub with an identifier for a different subject. The mechanics and assurance of subject-identifier translation are deployment-specific and are not otherwise standardized by this document.¶
The req_wl field and any Transaction Token fields other than actor-profile claims remain governed by [I-D.ietf-oauth-transaction-tokens] and local policy. Under this profile, req_wl is supporting workload context and MUST NOT be treated as a substitute for the outermost act.sub.¶
The TTS MUST verify that adding a new outermost act object would not cause the chain depth to exceed the limit in Section 3.8. If it would, the TTS MUST reject the request with invalid_request.¶
Before preserving or extending any inbound act chain, the TTS MUST validate the inbound token and trust the issuer that conveyed the chain. For the outermost inbound act object, which always represents the outermost actor the TTS is acting upon, the TTS MUST:¶
verify that act.iss is authoritative for the identifier namespace of the corresponding act.sub, using local trust mechanisms equivalent in strength to those described in Section 4.2 step 3; and¶
evaluate the delegation relationship per local policy, as described in Section 4.2 step 4.¶
Interoperable processing is defined around sub and the outermost act.sub. If local policy additionally uses inner act objects from the inbound chain to make access-control or scope decisions (beyond carrying them as audit history), the TTS SHOULD apply the same validation as for the outermost entry. For inner act objects that the TTS preserves solely as prior-actor context (carried forward for audit purposes without driving any security decision), the TTS MAY rely on trust in the outer token issuer rather than independently validating each prior hop. The TTS MUST NOT treat prior-context inner actors as independently authenticated merely because they appear in the re-issued token. If local policy treats an inner actor as a security-relevant input but cannot validate it to the assurance level required by that policy, the TTS SHOULD reject the request with invalid_grant.¶
Before creating a new outermost act object, the TTS MUST evaluate whether the newly authenticated presenter is authorized under local policy to act on behalf of sub for the requested transaction. If local policy explicitly prohibits that (sub, new presenter) relationship, the TTS MUST reject the request with access_denied. If the required actor relationship is absent or cannot be confirmed from the current inputs and policy, the TTS MUST reject the request with actor_unauthorized.¶
Because the issued Transaction Token carries delegated actor information, the TTS MUST include a top-level iss claim identifying itself as the Transaction Token issuer, and it MUST create a new outermost act object for the new presenter:¶
The TTS MUST set act.sub to the new presenter's identifier.¶
The TTS MUST set act.iss to the issuer namespace authoritative for the new presenter's identifier. This obligation applies only to the act object the TTS creates for the current presenter. The TTS MUST NOT rewrite act.iss or any other field in act objects inherited from the inbound token; those entries were authored by upstream ASes and their content is fixed at the point of authorship.¶
If the inbound token already carries an act chain, the TTS MUST nest it beneath the new outermost act.¶
The TTS SHOULD set act.sub_profile based on its knowledge of the new presenter's entity type.¶
When the issued Transaction Token includes a top-level presenter-binding claim such as cnf, that binding applies to the current presenter. The underlying presenter-authentication and proof mechanism is defined by [I-D.ietf-oauth-transaction-tokens] and any applicable deployment profile, not by this document.¶
Transaction Token fields other than actor-profile claims, including scope, tctx, and rctx, are defined by [I-D.ietf-oauth-transaction-tokens] and local policy. This document does not standardize their issuance semantics.¶
These same preservation rules apply regardless of whether the inbound credential is a JWT assertion grant, a JWT access token, or a Transaction Token, provided that the TTS supports issuing a Transaction Token from that input. This document does not define direct Transaction Token issuance from ID tokens or refresh tokens.¶
This chapter defines actor-profile-specific error handling for authorization servers and Transaction Token Services under this profile.¶
When an AS rejects a request under this profile for reasons related to actor-profile validation, it MUST return an OAuth error response per [RFC6749], Section 5.2 and [RFC8693], Section 2.2. The following error codes apply across all token types defined in this profile. They do not override invalid_client when a request fails client authentication per [RFC6749] or [RFC7523].¶
invalid_request:Use when the act claim structure is syntactically invalid, the delegation chain depth exceeds the limit in Section 3.8, a required claim (act.sub or act.iss) is absent, a delegated Transaction Token omits the required top-level iss, or a DPoP-bound JWT assertion grant omits the required top-level cnf.jkt.¶
invalid_grant:Use when the assertion or subject token cannot be validated, the issuer is not trusted to assert the delegation relationship, or the request's required proof-of-possession check cannot be confirmed.¶
access_denied:Use when AS policy explicitly prohibits the identified actor (act.sub) from acting on behalf of the subject (sub) for the requested resource or scope, and the prohibition is a definitive policy decision (not a transient or recoverable failure).¶
actor_unauthorized:Use when the request fails a remediable actor-policy check for the (sub, act.sub) pair. Examples include: the actor's sub_profile is not in the accepted set, the delegation relationship required by local policy is absent or could not be confirmed from current inputs, or the actor lacks the delegation grant required for the requested scope. This code allows clients and agent orchestrators to distinguish actor policy mismatches from credential or structural failures. access_denied remains for explicit deny policy rather than input-contingent actor-policy mismatch.¶
The error_description field SHOULD be included and SHOULD describe which aspect of actor-profile validation failed, to the extent permitted by the AS's security and privacy policy.¶
When a client or agent orchestrator receives actor_unauthorized, it SHOULD attempt the following remediation steps in order:¶
Consult entity_profiles_supported.actor in AS metadata (Section 10.2.2) to determine whether the actor's sub_profile is in the accepted set. If not, the AS does not support this actor type for the resource; the failure is terminal for this actor identity.¶
If the sub_profile is in the accepted set, inspect error_description to determine whether the failure is due to a missing or unconfirmed delegation grant. If so, obtain or register the delegation grant before retrying.¶
If neither step resolves the failure, consult deployment documentation or contact the resource owner to determine whether any path to authorization exists for this (sub, act.sub) pair and scope.¶
If no remediation path exists, treat the failure as terminal for this delegation path.¶
actor_unauthorized is distinct from access_denied, which represents a definitive policy prohibition. Receiving actor_unauthorized does not preclude retrying with a different actor credential that may satisfy the AS's actor policy.¶
Example of a definitive prohibition:¶
{
"error": "access_denied",
"error_description": "actor is explicitly denied access for this subject"
}
¶
Example of an actor not authorized for the requested scope:¶
{
"error": "actor_unauthorized",
"error_description": "act.sub_profile not accepted for payments:create"
}
¶
When a TTS rejects a request for reasons related to actor-profile processing, it MUST return an OAuth error response per [RFC6749], Section 5.2 and [RFC8693], Section 2.2. The following error codes apply:¶
invalid_request:Use when the inbound token's act claim structure is syntactically invalid, the delegation chain depth would exceed the limit in Section 3.8, a required actor-profile claim (act.sub or act.iss) is absent from an act object in the inbound token, or a delegated Transaction Token omits the required top-level iss claim.¶
invalid_grant:Use when the inbound token fails validation, the sub identity cannot be preserved per step 1 of Section 7.4, or inbound actor information that the TTS relies on for security-relevant processing cannot be validated per step 4 of Section 7.4.¶
access_denied:Use when local TTS policy explicitly prohibits the requesting workload from acting in the delegation chain for the identified subject, and the prohibition is a definitive policy decision.¶
actor_unauthorized:Use when the request fails a remediable actor-policy check for the (sub, act.sub) pair in the requested transaction, including the newly authenticated presenter the TTS would install as the new outermost actor. Examples include: the act.sub_profile of an inbound actor is not in the accepted set for this TTS, or the delegation relationship required by local policy is absent or could not be confirmed from current inputs. As with the equivalent AS error code (Section 8.1), this code signals an input-contingent actor-policy mismatch rather than a structural, credential, or explicit deny decision.¶
The error_description field SHOULD be included and SHOULD describe which aspect of actor-profile processing failed, to the extent permitted by the TTS's security and privacy policy.¶
This chapter covers how the actor profile integrates with adjacent protocol mechanisms for actor classification and capability discovery.¶
[I-D.mora-oauth-entity-profiles] defines the OAuth Entity Profiles mechanism, including the sub_profile and client_profile JWT claims, the entity_profiles_supported AS metadata parameter with its client, subject, and actor arrays, and an IANA registry of entity profile values with associated usage locations, including the "Actor Profile" usage location. It also explicitly defines sub_profile within act (Actor) nodes per [RFC8693] for classification of delegated actors in delegation chains.¶
This document uses the actor profile support defined in [I-D.mora-oauth-entity-profiles]. The sub_profile claim within an act object classifies the entity identified by act.sub, using values registered with the "Actor Profile" usage location in the "OAuth Entity Profiles" registry. The entity_profiles_supported.actor array in AS metadata advertises which actor entity profile values are accepted, as defined in [I-D.mora-oauth-entity-profiles].¶
The values registered for actor use are defined in [I-D.mora-oauth-entity-profiles]. Values within act.sub_profile MUST be either registered with the "Actor Profile" usage location in the "OAuth Entity Profiles" registry or privately defined collision-resistant values (see Section 3.6). When processing act.sub_profile, issuers and consumers MUST treat registered values according to the entity profile semantics defined in [I-D.mora-oauth-entity-profiles] and MUST NOT reject tokens solely because a value is unrecognized (see Section 3.7).¶
This document makes no independent requests to the "OAuth Entity Profiles" registry; all actor-profile-related registry definitions are provided by [I-D.mora-oauth-entity-profiles].¶
This section defines a minimal set of metadata parameters that, together with the entity_profiles_supported.actor array defined in [I-D.mora-oauth-entity-profiles], allow authorization servers and resource servers to advertise actor-profile support without out-of-band configuration. These parameters provide partial capability signaling only; they do not provide a complete machine-readable description of every supported grant path or method by which the AS determines the acting party. Metadata helps clients detect likely incompatibilities, but it does not guarantee successful token issuance or resource access and does not define a required client workflow.¶
The design principle is that capability flags go in this spec's metadata; entity type enumeration goes in [I-D.mora-oauth-entity-profiles] metadata. When these metadata are available, clients can use entity_profiles_supported.actor per [I-D.mora-oauth-entity-profiles] to assess which actor entity profiles the associated AS accepts under this profile, can use actor_profile_token_types_supported (Section 10.2.2) to assess which delegated output token types the AS advertises under this profile, and can use actor_profile_actor_token_profiles_supported to assess which actor_token credential profiles the AS advertises for Token Exchange.¶
Two new parameters are defined for use in Protected Resource Metadata ([RFC9728]):¶
actor_profile_required:OPTIONAL. A boolean. When true, the RS indicates that delegated requests for this resource are expected to provide actor-profile information conforming to this document's semantics. For JWT access tokens and Transaction Tokens, this ordinarily means a token carrying an act claim conforming to this profile. In deployments that use opaque access tokens, equivalent actor-profile information MAY instead be conveyed to the RS via introspection, but such support is deployment-specific and the opaque token itself is not conformant to this profile. Clients SHOULD treat this as a strong indication that delegated access will require either a conforming act claim in the token or an explicitly documented opaque-token/introspection path providing equivalent claims. An RS that enforces this policy for a given request path MUST reject delegated requests for which neither a conforming act claim nor equivalent introspection-derived actor-profile information is available to the RS. When false or absent, actor-profile conformance is not advertised by metadata. This parameter is resource-scoped, not path-scoped; [RFC9728] does not define sub-resource granularity for Protected Resource Metadata. An RS that requires actor-profile conformance only on specific request paths (e.g., /payments but not /profile) MUST apply enforcement at the request layer. Such an RS MAY set this parameter to true as a conservative resource-wide signal, but clients and deployment documentation SHOULD recognize that path-specific enforcement can be stricter than resource metadata alone expresses.¶
actor_authorization_required:OPTIONAL. A boolean. When true, the RS signals that it ordinarily evaluates the actor as an authorization input in addition to the subject, as described in Section 9. Clients SHOULD treat this as meaning that actor-profile information is likely required for delegated access. An RS that advertises this parameter SHOULD evaluate the (sub, outermost act.sub) relationship on the request paths for which it intends that signal to apply and therefore will ordinarily require a conforming act claim for self-contained tokens or equivalent act information via introspection in opaque-token deployments. When false or absent, the RS makes no metadata declaration to clients about whether actor authorization is applied.¶
actor_profile_max_chain_depth:OPTIONAL. A positive integer indicating the maximum delegation chain depth that this RS will accept in tokens presented to it. When absent, the RS makes no commitment about supported depth beyond what Section 3.8 requires. Clients SHOULD use this value when constructing multi-hop chains to avoid presenting tokens the RS will reject.¶
Clients discover which actor entity profile values the RS's AS will accept by consulting entity_profiles_supported.actor in the AS metadata for the AS listed in the resource's authorization_servers.¶
Example Protected Resource Metadata fragment:¶
{
"resource": "https://api.travel-provider.example",
"authorization_servers": [
"https://as.travel-provider.example"
],
"actor_profile_required": true,
"actor_authorization_required": true,
"actor_profile_max_chain_depth": 3
}
¶
Transaction Token support is advertised using the transaction_token_supported AS metadata parameter and the transaction_token_required Protected Resource Metadata parameter, both defined in [I-D.ietf-oauth-transaction-tokens], Section 8. This document does not redefine those parameters. When an AS or TTS can issue Transaction Tokens as delegated outputs under this profile, it MUST list urn:ietf:params:oauth:token-type:txn_token in actor_profile_token_types_supported.¶
Clients can use Protected Resource Metadata ([RFC9728]) to determine whether a resource advertises actor-profile conformance (actor_profile_required), authorization of the (sub, outermost act.sub) pair (actor_authorization_required), and any advertised resource-side chain-depth limit (actor_profile_max_chain_depth). Clients can use the associated AS metadata ([RFC8414]) to determine whether the AS advertises compatible delegated output token types (actor_profile_token_types_supported), accepted actor_token credential profiles (actor_profile_actor_token_profiles_supported), accepted actor entity profiles (entity_profiles_supported.actor), and any AS-side chain-depth limit (actor_profile_max_chain_depth). For Transaction Token paths, clients SHOULD additionally consult the transaction-token metadata described in Section 10.2.4.¶
These signals are advisory capability indicators, not a complete machine-readable description of every supported grant path. A client that detects an obvious mismatch, such as an unsupported delegated output token type, an unsupported actor_token credential profile, an actor entity profile outside the advertised accepted set, or a required chain depth that exceeds an advertised maximum, will ordinarily avoid that path or rely on deployment-specific configuration. As a safe default, a client that intends to make a request on behalf of another principal should treat actor_profile_required: true as indicating that it likely needs an explicit act-carrying token for that resource, unless deployment documentation explicitly defines a delegated opaque-token path in which introspection supplies equivalent actor-profile claims.¶
When a delegated request explicitly carries actor-profile claims and act.sub_profile is included, its value SHOULD be drawn from the entity_profiles_supported.actor accepted list when that metadata is available. When actor information is instead derived by the AS from authenticated client context or other local policy, metadata and deployment documentation can help a client assess whether the resulting token is likely to satisfy the resource's delegated-token expectations.¶
Example client preflight failure:¶
If the RS metadata advertises "actor_profile_required": true, but the target AS metadata advertises "entity_profiles_supported": { "actor": ["service"] } and the client's acting entity profile is ai_agent, the client would ordinarily stop before making the token request because the AS does not advertise support for the actor type the client would need to represent.¶
This chapter provides deployment and migration guidance for adopting the OAuth Actor Profile in systems that currently rely on implicit delegation or older act semantics.¶
This profile extends the base act claim semantics from [RFC8693] by unconditionally requiring iss in every act object, and by defining sub_profile and optional actor-scoped confirmation semantics. Deployments that receive an act object that conforms only to [RFC8693] but omits this profile's required members MUST treat that actor object as not conforming to this profile.¶
When a token or assertion is required by local policy or advertised metadata to conform to this profile, such non-conforming act objects MUST be rejected. When profile conformance is not required, implementations MAY continue to process a base [RFC8693] act object according to local policy, but they MUST NOT infer profile-defined semantics for claims that are absent.¶
The migration path for deployments currently using RFC 8693 act objects is:¶
ASes that issue tokens carrying act claims MUST begin emitting act.iss in all newly issued tokens once support for this profile is enabled. Existing consumers that do not recognize act.iss will ignore it.¶
Update consumers to validate act.iss per Section 3.6 once issuers have deployed step 1.¶
Once all token issuers and consumers on a given path have been updated, resource servers can enforce profile conformance by setting actor_profile_required: true in their Protected Resource Metadata. ASes that wish to accept only profile-conformant inbound assertions can do so via local policy once issuers on inbound paths have deployed step 1.¶
Steps 2 and 3 are RECOMMENDED; step 1 is REQUIRED for any AS that issues actor-profile tokens. This graduated approach avoids a flag-day cutover and allows incremental rollout across trust domains.¶
When an AS receives an inbound token or assertion whose act object omits act.iss (that is, the object conforms only to [RFC8693] and not to this profile):¶
If local policy or advertised metadata requires actor-profile conformance for the request path, the AS MUST reject the request. It MUST return invalid_request consistent with Section 8.1.¶
If actor-profile conformance is not required, the AS MAY process the inbound act object under local policy only for non-profile behavior. It MUST NOT rewrite an inherited actor entry to add act.iss, and it MUST NOT omit the inbound act claim from an issued token that would otherwise preserve or extend the chain under this profile. Any request path that would preserve or extend such a non-conforming chain into an actor-profile token MUST be rejected.¶
Implementations that previously treated confirmation members inside act as active sender-constraining mechanisms should note that this document defines proof-of-possession only through the top-level cnf claim and the immediate presenter. Deployments that relied on per-hop actor-key verification for multi-hop security properties will need a separate provenance mechanism or profile rather than the core actor profile defined here.¶
This document does not standardize whether an AS issues refresh tokens in response to delegated JWT assertion grant requests, how such refresh tokens are revoked, or whether later use of such refresh tokens requires re-presentation of upstream delegation artifacts. Those decisions remain deployment-specific. When a refresh token is later used to obtain a delegated output token, the actor-profile rules in Section 6.1.5.2 and the output-token rules of this document apply.¶
The invariant of this document is that client_id identifies the OAuth client registration, sub identifies the authorizing principal, and act.sub is the authoritative actor identity signal when delegation is present. Migration from implicit delegation is the process of making this distinction explicit in tokens where these roles were previously conflated through client_id or inferred from token-request context.¶
Deployments that currently rely on implicit delegation can migrate incrementally to this profile. During migration, existing client-oriented inputs such as client_id, azp, and authenticated client context MAY remain in use, but the outermost act.sub becomes the authoritative explicit delegation signal whenever act is present. A common transition pattern is to emit both legacy client-oriented identifiers and explicit actor claims during rollout, measure and reconcile mismatches, and then require act where explicit delegation is needed.¶
A deployment that chooses explicit delegation only can reject non-act delegated requests entirely and omit legacy client-identity reconciliation.¶
One safe migration pattern is:¶
If act is present, use the outermost act.sub as the authoritative delegated-actor signal.¶
Clients that can obtain explicit-delegation tokens under this profile SHOULD prefer those tokens over relying on legacy implicit client-identity interpretation.¶
If act is absent, deployments MAY continue to apply legacy implicit client-based policy according to local policy, and existing client-based authorization logic MAY remain in place during migration.¶
If both explicit and implicit signals are present and local policy expects them to identify the same party under trusted local mapping rules, implementations SHOULD apply those mapping rules and either reconcile the identifiers or treat them as distinct according to local policy.¶
If both are present and no such equivalence rule exists, implementations SHOULD treat them as distinct identifiers with different semantics rather than infer equivalence.¶
An RS that enforces explicit delegation under this profile for a given request path MUST NOT treat the successful presentation of a non-act token as an acceptable substitute for a delegated token merely because legacy client-based policy would otherwise allow the request.¶
During transition, issuers SHOULD emit both legacy client-oriented identifiers and explicit actor claims whenever doing so is feasible for the deployment.¶
Legacy implicit form:¶
{
"iss": "https://as.example.com",
"sub": "https://idp.example.com/users/alice",
"client_id": "travel-assistant-client-id",
"azp": "travel-assistant-client-id",
"scope": "booking:create"
}
¶
Explicit form:¶
{
"iss": "https://as.example.com",
"sub": "https://idp.example.com/users/alice",
"client_id": "travel-assistant-client-id",
"azp": "travel-assistant-client-id",
"act": {
"sub": "https://agents.example.com/travel-assistant",
"iss": "https://as.example.com",
"sub_profile": "ai_agent"
},
"scope": "booking:create"
}
¶
client_id and azp remain as auxiliary client-identity inputs; act.sub is the authoritative delegation signal. When local policy expects both to identify the same party under trusted local mapping rules, implementations SHOULD attempt to reconcile them under those rules; otherwise they SHOULD be treated as distinct or rejected according to local policy.¶
Mismatch example, where the client and actor identify different parties:¶
{
"iss": "https://as.example.com",
"sub": "https://idp.example.com/users/alice",
"client_id": "travel-assistant-client-id",
"act": {
"sub": "https://agents.other-provider.example/concierge-bot",
"iss": "https://as.other-provider.example",
"sub_profile": "ai_agent"
},
"scope": "booking:create"
}
¶
An AS or RS that expected the client and actor to identify the same party under trusted local mapping rules would typically reject this token unless those rules explicitly bind travel-assistant-client-id to https://agents.other-provider.example/concierge-bot. If no such mapping rule exists, the safer interpretation is to treat the identifiers as distinct.¶
This document does not define a trust framework for establishing namespace authority, proving delegation approval, or validating subject-identifier translation. Security for those decisions depends on deployment-specific policy and external agreements.¶
An attacker who can inject or forge act claims can impersonate an arbitrary actor and exercise a subject's permissions without authorization. The primary mitigation is to accept act claims only in tokens whose issuer is trusted to assert the delegated actor relationship. RS implementations MUST validate the token signature before extracting actor claims, and MUST verify that the token issuer is trusted to convey the claims it carries.¶
Because inner act objects are set by upstream ASes and not re-signed at each hop, the integrity of the entire delegation chain rests on the outermost token's signature. Implementations SHOULD use short token lifetimes and MUST reject tokens whose exp has passed, regardless of chain depth.¶
The act.iss values in inner act objects are assertion-based prior-actor context set by whoever constructed those objects at an earlier hop, not by the issuer of the current token. Implementations MUST NOT treat an inner act.iss as independently authenticated merely because it appears in the token; the trust basis is the outer token issuer's endorsement. Consequently: an RS that relies on inner act.iss for audit or policy MUST do so only when it trusts the outer issuer to have validated and faithfully propagated that chain; ASes that propagate inner chains SHOULD validate inner act.sub and act.iss entries only when local policy chooses to use those entries as additional inputs to issuance decisions per Section 4.2 step 5; and security policies relying on inner actor identities for access control SHOULD be treated as lower-assurance and deployment-specific relative to policies based on the outermost act.sub.¶
When a token crosses organizational boundaries, the receiving AS or RS MUST apply appropriate trust evaluation. ASes performing token exchange MUST evaluate cross-domain delegation grants explicitly and SHOULD NOT grant cross-domain actors the same rights as same-domain actors absent an explicit trust decision that makes them equivalent.¶
Client identity, such as client_id, azp, or authenticated client context, is widely used in deployed systems as an authorization input. Under this document, those values remain auxiliary client-identity signals, while the outermost act.sub is the explicit delegated-actor signal when present. The following normative rules apply:¶
When act is present, interoperable processing SHOULD use it as the explicit delegated-actor signal rather than substituting client_id, azp, or other client-identity signals. Deployments that rely on such substitution are outside the interoperable scope of this profile.¶
When a single client_id registration fronts multiple distinct acting entities (for example, an agent orchestration platform executing requests on behalf of different agent instances), client_id alone does not identify the runtime actor. Each such request SHOULD carry act.sub identifying the specific acting principal; deployments that rely on client_id alone for actor distinction in this scenario are operating outside the interoperable scope of this profile.¶
During token issuance, client_id and azp MUST NOT be rewritten to represent delegation state that belongs in act; see Section 6.3.2 for propagation rules.¶
When both explicit (act.sub) and implicit (client_id, azp) signals are present and local policy expects them to identify the same party, implementations SHOULD apply trusted local mapping rules and either reconcile the identifiers or treat them as distinct according to local policy.¶
When a protected resource or authorization path enforces explicit delegation under this profile, implementations MUST NOT downgrade to non-act processing solely because another token-acquisition path or legacy policy input remains available.¶
The detailed migration rules and transition patterns are defined in Section 11.4.¶
Without top-level presenter proof of possession, a leaked token can be replayed by any party.¶
The RS SHOULD require the presenter-proof mechanism appropriate to the token type and deployment for the top-level cnf.jkt or other top-level confirmation information. For example, JWT access tokens commonly use DPoP or mTLS, while Transaction Tokens can use the workload proof mechanism defined by their deployment profile.¶
Deployments that use sender-constrained tokens for delegated access SHOULD apply that protection to the current presenter to reduce delegation-token theft risk.¶
This document does not define per-hop actor-key provenance within the delegation chain. Stronger assurance for prior-hop provenance would require an additional mechanism outside the scope of this document, such as signed hop receipts, transparency-log-based recording, or another future extension.¶
Unbounded delegation chains increase attack surface and complicate policy evaluation. Depth support and interoperability requirements are defined in Section 3.8. Implementations that encounter chains exceeding their configured local maximum MUST reject the token to prevent denial-of-service through chain parsing.¶
The sub_profile claim is asserted by the token issuer and is only as trustworthy as that issuer. Resource servers MUST NOT trust sub_profile values in tokens issued by untrusted parties. Resource server operators SHOULD configure a list of accepted entity-type profiles per trust domain.¶
The revocation-related requirements in this section are limited to how this profile interacts with already-issued tokens and refresh behavior.¶
Token revocation ([RFC7009]) applies to individual tokens but does not revoke an underlying delegation relationship or invalidate already-issued downstream tokens in a delegation chain. When Alice revokes her delegation to an agent, access tokens already issued to downstream actors remain valid until their exp time. Short token lifetimes are the primary mitigation; see [I-D.ietf-oauth-security-topics] for general access token lifetime guidance.¶
The AS SHOULD refuse to issue new tokens for a (subject, actor) pair when it has authoritative knowledge that the delegation relationship has been revoked. Implementations MUST NOT use delegation chain depth as a rationale for skipping revocation checks.¶
When a deployment uses long-lived delegated refresh behavior, revocation of the delegation relationship may take effect later than it would in a model that requires re-presentation of a current upstream delegation artifact at each token request. This document does not standardize refresh-token revocation or revalidation policy; deployments should account for that tradeoff explicitly.¶
The internal mechanism by which an AS tracks delegation state (whether a formal registry, a consent store, a policy engine, or another form) is a deployment and product decision outside the scope of this document. Resource servers in security-sensitive deployments may use token introspection ([RFC7662], Section 9.5) when request-time revocation state is needed, or may rely on short token lifetimes; the choice of revocation strategy is deployment-specific.¶
A resource server that evaluates only the subject principal when an act claim is present is susceptible to a confused deputy attack: a malicious actor exploits a subject's pre-existing permissions without the subject's ongoing consent simply by presenting a token that names the subject in sub. The mitigation is authorization of the (sub, outermost act.sub) pair before granting access. Resource servers SHOULD implement such evaluation for delegated tokens under this document.¶
Several processing rules in this document tolerate an AS re-expressing sub in a different identifier namespace when local deployment policy treats the identifiers as referring to the same subject (see Section 6.3.2 step 2 and Section 7.4 step 1). This document does not standardize subject-translation mechanisms or proof of equivalence between subject namespaces. Such translation creates a subject-substitution risk: a malicious or misconfigured AS could map sub to a different entity in the new namespace, silently replacing the authorized principal with a different one.¶
Mitigations:¶
Receiving ASes and RSes SHOULD NOT accept sub translations from ASes they do not trust to authoritatively map identifiers between the two namespaces. Trust for namespace mapping is separate from trust for token signing and SHOULD be established explicitly in local policy.¶
Subject-namespace translation is a high-assurance operation and SHOULD be used only when the issuer has authoritative mapping information for both the original and translated namespaces.¶
When an AS translates sub, it SHOULD include both the original and translated identifiers, or otherwise provide enough context for the receiving party to verify the mapping, where local policy requires such verification.¶
RSes that enforce access control against a specific sub value SHOULD verify that the issuing AS is authoritative for the subject-identifier namespace used, and SHOULD NOT accept subject identifiers from namespaces for which the issuing AS is not authoritative.¶
If the receiving party cannot validate or otherwise trust that the translated sub still refers to the same underlying subject, it SHOULD reject the token rather than treat the translation as advisory.¶
The following abbreviated examples illustrate rejection cases that implementations are expected to handle:¶
act.iss where actor profile is enforced
{
"iss": "https://as.example.com",
"sub": "https://idp.example.com/users/alice",
"act": {
"sub": "https://agents.example.com/travel-assistant"
}
}
¶
This token is structurally non-conforming to this profile. An AS processing it as an input MUST reject it with invalid_request, and an RS enforcing actor_profile_required MUST reject it as non-conforming.¶
If a request would cause the resulting nested act chain to exceed the implementation's configured local maximum delegation depth, the issuer MUST reject the request with invalid_request; it MUST NOT silently truncate the chain.¶
An attacker who can present a token with a crafted sub_profile or actor chain could attempt to escalate privileges. ASes MUST validate inbound sub_profile values against the syntax requirements of this document, the applicable registry or deployment-specific allowed set where such checks are part of local policy, and the local policy applicable to the token they are issuing. They MUST preserve unrecognized but syntactically valid values as required by Section 3.7, and they MUST reject values that are malformed or disallowed by local policy.¶
Delegation chains can reveal sensitive information about user behavior, enterprise topology, software suppliers, and internal tool composition. Issuers therefore SHOULD disclose only the actor information needed by the relying party for authorization, audit, or policy enforcement.¶
Cross-domain deployments SHOULD prefer stable but non-reassigned identifiers and SHOULD consider pairwise identifiers for human subjects when a globally correlatable identifier is not required by the use case.¶
When the same logical entity can appear in different identifier namespaces, such as azp, req_wl, and act.sub, issuers and relying parties SHOULD use explicit issuer scoping and locally trusted mapping rules rather than string equality alone to determine whether those identifiers refer to the same entity.¶
Issuers SHOULD minimize disclosure of prior actors by audience and token-design decisions made before issuance. Once an issuer chooses to preserve a delegation chain in a token under this profile, it SHOULD preserve the validated chain intact for that token. If local privacy requirements would require omitting a chain element that would otherwise be security-relevant to the recipient's evaluation, the issuer SHOULD reject the request rather than silently truncating the chain.¶
The txn claim in Transaction Tokens ([I-D.ietf-oauth-transaction-tokens]) is a stable, globally unique identifier shared across all tokens in a single business transaction. When Transaction Tokens cross organizational boundaries, txn enables cross-domain correlation of all service calls within a transaction by any party that observes multiple tokens. Cross-domain propagation and lifetime rules for txn are governed by [I-D.ietf-oauth-transaction-tokens]; deployments SHOULD consult that specification's privacy guidance when propagating Transaction Tokens across trust-domain boundaries. This document notes that txn values, like other stable identifiers, should be treated as sensitive in contexts where cross-domain correlation of user activity is not required or authorized.¶
The act.sub_profile claim discloses the entity type of the actor, including values such as ai_agent that reveal that a request is being made by an automated agent on behalf of the subject. In some jurisdictions or deployment contexts, this disclosure may be legally significant or may reveal sensitive information about user behavior and tool composition that should not flow across trust-domain boundaries. Issuers SHOULD consider audience-specific disclosure constraints when including act.sub_profile in cross-domain tokens, and SHOULD omit or suppress actor entity-type values when the recipient does not require them for authorization, audit, or policy enforcement.¶
The req_wl claim in Transaction Tokens can also expose sensitive information about internal workload topology and service composition. Transaction Token Services SHOULD disclose req_wl only to relying parties that need that information for authorization, audit, or policy enforcement, and SHOULD avoid propagating internal-only workload identifiers across trust-domain boundaries unless such disclosure is explicitly required by the deployment.¶
This document requests IANA to register the following values in the "OAuth Protected Resource Metadata" registry ([RFC9728]):¶
Metadata Name: actor_profile_required¶
Metadata Description: Boolean indicating whether the RS advertises that delegated requests for this resource are expected to provide actor-profile information conforming to this document's semantics¶
Change Controller: IETF¶
Reference: Section 10.2.3 of this document¶
Metadata Name: actor_authorization_required¶
Metadata Description: Boolean indicating whether the RS advertises that it evaluates the actor as an authorization input in addition to the subject for delegated tokens¶
Change Controller: IETF¶
Reference: Section 10.2.3 of this document¶
Metadata Name: actor_profile_max_chain_depth¶
Metadata Description: Positive integer indicating the maximum delegation chain depth the RS will accept in tokens presented to it¶
Change Controller: IETF¶
Reference: Section 10.2.3 of this document¶
This document requests IANA to register the following value in the "OAuth Extensions Error Registry" ([RFC6749], Section 11.4):¶
This document requests IANA to register the following value in the "OAuth Token Introspection Response" registry ([RFC7662], Section 3.3):¶
Claim Name: chain_complete¶
Claim Description: Boolean indicating whether the act delegation chain in the introspection response is complete. When false, one or more inner act chain entries have been omitted from the response for privacy reasons. When absent, the chain SHOULD be treated as complete unless local policy or deployment context indicates otherwise.¶
Change Controller: IETF¶
Reference: Section 9.5 of this document¶
This document does not request independent JWT Claims Registry entries for the act object sub-claims (iss, sub_profile, cnf, and any extension claims) it defines or profiles. These values appear only within the JSON object value of the act claim, which is already registered in the JWT Claims Registry by [RFC8693]. Sub-object keys within a registered claim are scoped to that claim's JSON object and do not require separate top-level registry entries.¶
This document makes no independent requests to the "OAuth Entity Profiles" registry. It normatively depends on the "Actor Profile" usage location, the actor array in entity_profiles_supported, and the registration of user, service, and ai_agent with that usage location, all of which are defined and requested by [I-D.mora-oauth-entity-profiles]. The IANA actions for those entries are contingent on the progression of [I-D.mora-oauth-entity-profiles].¶
This appendix gives a non-AI example of the actor profile in a same-domain service-to-service delegation flow. A payroll batch processor acts on behalf of a human payroll administrator to call a payroll API; the payroll API then exchanges that access token for an internal Transaction Token used to write an audit record.¶
| Party | Identifier |
|---|---|
| Payroll Administrator |
https://idp.example.com/users/pat
|
| Enterprise AS |
https://as.example.com
|
| Payroll Batch Processor |
https://services.example.com/payroll-batch
|
| Payroll API |
https://services.example.com/payroll-api
|
| Audit TTS |
https://tts.example.com
|
| Audit Service |
https://internal.example.com/audit
|
The batch processor is an OAuth client and also the acting service. The client registration remains identified by client_id; the acting service is represented explicitly in act.sub.¶
The Enterprise AS issues a JWT access token for the Payroll API:¶
{
"iss": "https://as.example.com",
"sub": "https://idp.example.com/users/pat",
"sub_profile": "user",
"client_id": "payroll-batch-client",
"aud": "https://services.example.com/payroll-api",
"scope": "payroll:run",
"cnf": { "jkt": "SvcJKT-123" },
"act": {
"sub": "https://services.example.com/payroll-batch",
"iss": "https://as.example.com",
"sub_profile": "service"
}
}
¶
This is a single-hop actor object: act is present, but it contains no nested act. sub identifies the payroll administrator, while act.sub identifies the service exercising that administrator's authorization.¶
After processing the payroll request, the Payroll API exchanges the inbound access token at the Audit TTS to call the internal Audit Service. The Payroll API is the requesting workload (req_wl). The TTS validates the inbound actor chain, preserves it as an inner act, and adds a new outermost actor for the Payroll API:¶
{
"iss": "https://tts.example.com",
"sub": "https://idp.example.com/users/pat",
"sub_profile": "user",
"req_wl": "https://services.example.com/payroll-api",
"aud": "https://internal.example.com/audit",
"scope": "audit:create",
"txn": "550e8400-e29b-41d4-a716-446655440099",
"cnf": { "jkt": "ApiJKT-456" },
"act": {
"sub": "https://services.example.com/payroll-api",
"iss": "https://as.example.com",
"sub_profile": "service",
"act": {
"sub": "https://services.example.com/payroll-batch",
"iss": "https://as.example.com",
"sub_profile": "service"
}
}
}
¶
The subject remains the payroll administrator. The new outermost actor is the Payroll API (the workload presenting the exchange request), and the preserved inner actor is the payroll batch processor. This example demonstrates that the profile applies equally to non-AI service delegation and to transformations from a single-hop actor object into a multi-hop actor chain.¶
This appendix traces a single user request across two trust domains, highlighting the actor-profile claim structures and processing requirements specific to this document. Standard validation steps (JWT signature verification, sender-constrained access token proof, Transaction Token presenter proof, and Token Exchange mechanics) are delegated to the underlying token specifications and deployment profile.¶
All claim values, JKT thumbprints, and domain names are synthetic.¶
Alice's travel-assistant agent authenticates to the Enterprise IdP AS to obtain an ID Token. The agent then performs a Token Exchange at the same AS to obtain the ID-JAG. The ID-JAG is then presented to the Travel Provider AS using the JWT bearer grant, as described in Section 4.2. The agent exchanges the ID-JAG for an access token at the Travel Provider AS and calls the Booking Tool API. The Booking Tool exchanges the access token for a Transaction Token to call an internal inventory service.¶
Enterprise domain Travel Provider domain
──────────────────────────── ──────────────────────────────────────
Alice
│ (1) authenticates
▼
Enterprise IdP AS ─► ID Token
│ (2) Token Exchange (ID Token → ID-JAG)
▼
Enterprise IdP AS ─► ID-JAG
│ (3) JWT Bearer Grant (ID-JAG → AT)
└─────────────────► Travel Provider AS ─► AT
│
Travel Assistant ◄─────┘
│ (4) Access Token + DPoP
▼
Booking Tool API (RS)
│ (5) Token Exchange (AT → Transaction Token)
▼
Travel Provider TTS ─► Transaction Token
│ (6) Transaction Token + WIMSE proof
▼
Inventory Service (RS)
¶
| Party | Identifier | Trust Domain |
|---|---|---|
| Alice |
https://idp.enterprise.example/users/alice
|
Enterprise |
| Enterprise IdP AS |
https://as.enterprise.example
|
Enterprise |
| Travel Assistant |
https://agents.enterprise.example/travel-assistant
|
Enterprise |
| Travel Provider AS |
https://as.travel-provider.example
|
Travel Provider |
| Travel Provider TTS |
https://tts.travel-provider.example
|
Travel Provider |
| Booking Tool |
https://tools.travel-provider.example/booking-tool
|
Travel Provider |
| Inventory Service |
https://internal.travel-provider.example/inventory
|
Travel Provider |
Presenter key bindings:¶
| Principal | JWK Thumbprint (jkt) |
|---|---|
| Travel Assistant |
AgentJKT-NzbLsXh8uDCcd7MN
|
| Booking Tool |
ToolJKT-0ZcOCORZNYy9ZhHi
|
The agent consults the Travel Provider AS metadata (Section 10.2) as an advisory compatibility check before initiating the flow:¶
{
"issuer": "https://as.travel-provider.example",
"actor_profile_token_types_supported": [
"urn:ietf:params:oauth:token-type:jwt",
"urn:ietf:params:oauth:token-type:access_token",
"urn:ietf:params:oauth:token-type:txn_token"
],
"entity_profiles_supported": {
"subject": ["user", "ai_agent"],
"actor": ["user", "ai_agent", "service"]
}
}
¶
The agent observes that its sub_profile (ai_agent) is listed in entity_profiles_supported.actor and that delegated JWT assertion grants and delegated access tokens are advertised as output types in actor_profile_token_types_supported. These metadata do not by themselves advertise acceptance of JWT subject_token or JWT actor_token inputs, and they do not by themselves advertise support for the more specific ID-JAG token type used later in this flow. Together with grant_types_supported, the ID-JAG specification, and deployment documentation, they indicate that the delegated-token path is plausibly compatible with the Booking Tool RS's advertised requirements.¶
Alice authenticates to the Enterprise IdP AS. The profile-relevant claim is sub_profile, which propagates Alice's entity type into downstream tokens:¶
{
"iss": "https://as.enterprise.example",
"sub": "https://idp.enterprise.example/users/alice",
"sub_profile": "user",
"aud": "https://agents.enterprise.example/travel-assistant",
"exp": 1743379200,
"iat": 1743375600
}
¶
The agent presents Alice's ID Token to the Enterprise IdP AS using Token Exchange. In this example, the same JWT is used both as the RFC 7523 client_assertion and as the Token Exchange actor_token, making the authenticated client's actor identity explicit. The Enterprise IdP AS authenticates the client as https://agents.enterprise.example/travel-assistant, verifies that the ID Token audience matches that client, and uses local delegation policy plus that explicit actor credential to construct the actor-profile claims in the issued ID-JAG:¶
POST /token HTTP/1.1 Host: as.enterprise.example Content-Type: application/x-www-form-urlencoded DPoP: <AgentJKT-proof> grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange &subject_token=<alice-id-token> &subject_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Aid_token &requested_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Aid-jag &audience=https%3A%2F%2Fas.travel-provider.example%2F &resource=https%3A%2F%2Fas.travel-provider.example &scope=booking%3Acreate &client_id=https%3A%2F%2Fagents.enterprise.example%2Ftravel-assistant &client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer &client_assertion=<travel-assistant-client-assertion> &actor_token=<travel-assistant-client-assertion> &actor_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Ajwt¶
The Enterprise IdP AS applies scope reduction and validates the client-bound proof-of-possession according to RFC 9449. In this example, it binds the issued ID-JAG to the key demonstrated in the DPoP proof, validates the shared JWT under both the client-authentication and actor_token rules for RFC 7523 client assertions, determines from local policy that the authenticated client is the delegated actor for Alice in this flow, and issues the ID-JAG as a JWT output of token exchange with the actor chain established per Section 3:¶
{
"iss": "https://as.enterprise.example",
"sub": "https://idp.enterprise.example/users/alice",
"sub_profile": "user",
"client_id": "https://agents.enterprise.example/travel-assistant",
"azp": "https://agents.enterprise.example/travel-assistant",
"aud": "https://as.travel-provider.example/token",
"jti": "ent-idj-20260401-001",
"exp": 1743379200,
"iat": 1743375600,
"scope": "booking:create",
"cnf": { "jkt": "AgentJKT-NzbLsXh8uDCcd7MN" },
"act": {
"sub": "https://agents.enterprise.example/travel-assistant",
"iss": "https://as.enterprise.example",
"sub_profile": "ai_agent"
}
}
¶
The act object records the agent as the authorized actor. The client_id and azp values identify the OAuth client used in the exchange, while act.sub identifies the delegated actor. In this example those identifiers are the same URI, so the shared RFC 7523 client assertion and actor_token remain conformant with [RFC7523] while still making the actor explicit in the issued token. The top-level cnf.jkt is set to AgentJKT because the agent is the current presenter at this stage.¶
The agent presents the ID-JAG as a JWT Bearer authorization grant ([RFC7523]) to the Travel Provider AS. In this usage, the ID-JAG functions as a profiled JWT assertion grant, so the processing rules in Section 4.2 apply to it:¶
POST /token HTTP/1.1 Host: as.travel-provider.example Content-Type: application/x-www-form-urlencoded DPoP: <AgentJKT-proof> grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer &assertion=<id-jag> &scope=booking%3Acreate¶
The Travel Provider AS performs actor-profile processing per Section 4.2: it verifies the request's DPoP proof against the top-level cnf.jkt in the inbound ID-JAG and checks that act.sub_profile (ai_agent) is permitted as an actor for the requested scope under local policy. It issues an access token preserving the actor chain:¶
{
"iss": "https://as.travel-provider.example",
"sub": "https://idp.enterprise.example/users/alice",
"sub_profile": "user",
"client_id": "https://agents.enterprise.example/travel-assistant",
"azp": "https://agents.enterprise.example/travel-assistant",
"aud": "https://api.travel-provider.example",
"jti": "tp-at-20260401-001",
"exp": 1743379200,
"iat": 1743375600,
"scope": "booking:create",
"cnf": { "jkt": "AgentJKT-NzbLsXh8uDCcd7MN" },
"act": {
"sub": "https://agents.enterprise.example/travel-assistant",
"iss": "https://as.enterprise.example",
"sub_profile": "ai_agent"
}
}
¶
Alice's sub and sub_profile are preserved verbatim from the ID-JAG (Section 6.3.2). The Travel Provider AS does not translate or substitute the enterprise subject identifier. The client_id and azp values continue to identify the OAuth client, but they do not replace act.sub as the authoritative delegated-actor identifier.¶
The agent presents the access token with a DPoP proof:¶
POST /bookings HTTP/1.1
Host: api.travel-provider.example
Authorization: DPoP <tp-access-token>
DPoP: <AgentJKT-proof>
Content-Type: application/json
{"origin": "SFO", "destination": "NYC", "depart": "2026-04-15"}
¶
The Booking Tool RS applies authorization of the (sub, outermost act.sub) pair (Section 9): it evaluates Alice (sub, sub_profile: user) together with the Travel Assistant (act.sub, sub_profile: ai_agent) for the requested operation. Because the RS advertises actor_authorization_required: true, the (sub, outermost act.sub) relationship MUST satisfy local policy. The act.sub_profile value is checked against entity_profiles_supported.actor per Section 10.1.¶
The Booking Tool cannot reuse the received access token for internal calls: it is sender-constrained to AgentJKT, which the Booking Tool does not possess. It requests a Transaction Token from the TTS. In this example, the TTS receives the Booking Tool's WIMSE Workload Identity Token (WIT) as the Token Exchange actor_token and validates a Workload Proof Token (WPT). The WIT identifies the Booking Tool and carries its confirmation key, while the WPT proves possession of that key and binds the request to the accompanying access token:¶
POST /token HTTP/1.1
Host: tts.travel-provider.example
Content-Type: application/x-www-form-urlencoded
Workload-Proof-Token: <tool-wpt-with-wth-and-ath>
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Atoken-exchange
&subject_token=<tp-access-token>
&subject_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Aaccess_token
&actor_token=<booking-tool-wit>
&actor_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Ajwt
&requested_token_type=urn%3Aietf%3Aparams%3Aoauth%3Atoken-type%3Atxn_token
&audience=https%3A%2F%2Ftravel-provider.example
&scope=inventory%3Acheck
&rctx={"req_ip":"198.51.100.42"}
¶
The WIT is therefore the JWT actor_token defined by this profile, while the WPT provides the accompanying proof of possession required by the workload-credential profile.¶
The TTS applies actor-profile processing per Section 7.4: it preserves sub and sub_profile from the subject token, sets req_wl to the authenticated Booking Tool, and creates a new outermost act object for the Booking Tool while nesting the subject token's existing act claim beneath it. In this WIMSE-based deployment, the underlying Transaction Token mechanism also binds the issued token to the Booking Tool's presenter key (ToolJKT) identified in the WIT confirmation claim:¶
{
"iss": "https://tts.travel-provider.example",
"sub": "https://idp.enterprise.example/users/alice",
"sub_profile": "user",
"scope": "inventory:check",
"req_wl": "https://tools.travel-provider.example/booking-tool",
"aud": "https://travel-provider.example",
"jti": "txn-tok-20260401-001",
"txn": "550e8400-e29b-41d4-a716-446655440001",
"exp": 1743375750,
"iat": 1743375650,
"tctx": {
"action": "check-availability",
"origin": "SFO",
"destination": "NYC",
"depart": "2026-04-15"
},
"rctx": { "req_ip": "198.51.100.42" },
"cnf": { "jkt": "ToolJKT-0ZcOCORZNYy9ZhHi" },
"act": {
"sub": "https://tools.travel-provider.example/booking-tool",
"iss": "https://as.travel-provider.example",
"sub_profile": "service",
"act": {
"sub": "https://agents.enterprise.example/travel-assistant",
"iss": "https://as.enterprise.example",
"sub_profile": "ai_agent"
}
}
}
¶
The presenter binding rotates at this step: cnf.jkt is now ToolJKT because the Booking Tool is the current presenter. The nested actor chain records that the Booking Tool is now the current actor and that the Travel Assistant was the prior delegated actor.¶
GET /inventory?origin=SFO&dest=NYC&depart=2026-04-15 HTTP/1.1 Host: internal.travel-provider.example Txn-Token: <txn-token> Workload-Identity-Token: <booking-tool-wit> Workload-Proof-Token: <tool-wpt-with-wth-and-tth>¶
The Inventory Service validates the WIT and WPT according to the WIMSE specifications: the WPT proves possession of the key identified by the WIT, wth binds the proof to the presented WIT, and tth binds it to the presented Transaction Token. The Inventory Service then applies authorization of the (sub, outermost act.sub) pair (Section 9): Alice (sub) governs data access policy (e.g., travel tier), and the Booking Tool (act.sub) is the authorized internal workload for that request. The req_wl claim provides consistent TTS workload context for the same service in this example. The nested act.act.sub (Travel Assistant) is carried as prior delegation context and is not evaluated for access control at this internal tier, consistent with the guidance on inner actors in Section 9.2.¶
| Step | Token | sub | req_wl | act.sub (outermost) | act.act.sub (nested) | cnf.jkt |
|---|---|---|---|---|---|---|
| 1 | ID Token | Alice | — | — | — | — |
| 2 | ID-JAG | Alice | — | Travel Assistant | — | AgentJKT |
| 3 | Access Token | Alice | — | Travel Assistant | — | AgentJKT |
| 4 | (API call) | Alice | — | Travel Assistant | — | AgentJKT |
| 5 | Transaction Token | Alice | Booking Tool | Booking Tool | Travel Assistant | ToolJKT |
| 6 | (internal call) | Alice | Booking Tool | Booking Tool | Travel Assistant | ToolJKT |
Key observations:¶
In this example, sub (Alice) is unchanged across all trust domains and token transformations.¶
The presenter-binding key rotates once, at Step 5 when the TTS re-binds the Transaction Token to the Booking Tool's key.¶
At Step 5 the TTS creates a new outermost act for the Booking Tool and nests the prior act chain beneath it.¶
The author thanks the OAuth Working Group for the foundational work on Token Exchange (RFC 8693), JWT-formatted access tokens (RFC 9068), DPoP (RFC 9449), and Transaction Tokens, upon which this document builds. The motivating use cases for this work emerged from the deployment of AI agent systems that require cross-domain delegation with explicit actor chains and carried-forward delegation state within the trust model of the issuing domains.¶