<?xml version="1.0" encoding="utf-8"?>
<!-- name="GENERATOR" content="github.com/mmarkdown/mmark Mmark Markdown Processor - mmark.miek.nl" -->
<rfc version="3" ipr="trust200902" docName="draft-mw-spice-actor-chain-01" submissionType="IETF" category="std" xml:lang="en" xmlns:xi="http://www.w3.org/2001/XInclude" indexInclude="true">

<front>
<title abbrev="SPICE-ACTOR-CHAINS">Cryptographically Verifiable Actor Chains for OAuth 2.0 Token Exchange</title><seriesInfo value="draft-mw-spice-actor-chain-01" stream="IETF" status="standard" name="Internet-Draft"></seriesInfo>
<author initials="A." surname="Prasad" fullname="A Prasad"><organization>Oracle</organization><address><postal><street></street>
</postal><email>a.prasad@oracle.com</email>
</address></author><author initials="R." surname="Krishnan" fullname="Ram Krishnan"><organization>JPMorgan Chase &amp; Co</organization><address><postal><street></street>
</postal><email>ramkri123@gmail.com</email>
</address></author><author initials="D." surname="Lopez" fullname="Diego R. Lopez"><organization>Telefonica</organization><address><postal><street></street>
</postal><email>diego.r.lopez@telefonica.com</email>
</address></author><author initials="S." surname="Addepalli" fullname="Srinivasa Addepalli"><organization>Aryaka</organization><address><postal><street></street>
</postal><email>srinivasa.addepalli@aryaka.com</email>
</address></author><date year="2026" month="March" day="16"></date>
<area>Security</area>
<workgroup>SPICE</workgroup>
<keyword>actor chain</keyword>
<keyword>spice</keyword>
<keyword>oauth</keyword>
<keyword>rfc8693</keyword>
<keyword>token exchange</keyword>
<keyword>workload identity</keyword>
<keyword>delegation</keyword>
<keyword>AI agents</keyword>
<keyword>MCP</keyword>
<keyword>A2A</keyword>

<abstract>
<t>This document defines five actor-chain profiles for OAuth 2.0 Token Exchange
{{!RFC8693}}. {{!RFC8693}} permits nested <tt>act</tt> claims, but prior actors remain
informational only and token exchange does not define how a delegation path is
preserved and validated across successive exchanges.</t>
<t>This document defines profile-specific processing for linear multi-hop
workflows. The profiles are Asserted Delegation Path, Selectively Disclosed
Asserted Delegation Path, Committed Delegation Path, Commitment-Only
Delegation Path, and Selectively Disclosed Committed Delegation Path.</t>
<t>These profiles preserve the existing meanings of <tt>sub</tt> and <tt>act</tt>, support same-
domain and cross-domain delegation, require sender-constrained tokens, and
provide different tradeoffs among readable chain-based authorization,
cryptographic accountability, auditability, privacy, and long-running workflow
support.</t>
</abstract>

</front>

<middle>

<section anchor="introduction"><name>Introduction</name>
<t>In service-to-service, tool-calling, and agent-to-agent systems, a workload
often receives a token, performs work, and then exchanges that token to call
another workload. This pattern appears in microservices, workload identity
systems, MCP-style tool invocation, and AI-agent orchestration pipelines. The
resulting path can span multiple hops and multiple Authorization Servers
(ASes).</t>
<t>defines token exchange and the <tt>act</tt> claim for the current actor,
but it does not define a standardized model for preserving and validating the
full delegation path across successive exchanges.</t>
<t>This document defines cryptographically verifiable actor-chain profiles for
OAuth 2.0 Token Exchange.</t>
<t>For compactness on the wire, tokens and token-carried commitment objects use
the compact names <tt>achp</tt> (actor-chain profile), <tt>ach</tt> (actor chain), and
<tt>achc</tt> (actor-chain commitment). OAuth request parameters and metadata remain
descriptive.</t>

<ul spacing="compact">
<li><tt>sub</tt> continues to identify the token subject.</li>
<li><tt>act</tt>, when present, continues to identify the current actor.</li>
<li><tt>ach</tt>, when present, carries the ordered delegation path.</li>
<li><tt>achc</tt>, when present, carries cumulative committed chain
state for stronger tamper evidence and auditability.</li>
</ul>
<t>The design separates:</t>

<ul spacing="compact">
<li><strong>inline authorization</strong>, where ordinary tokens carry what the next hop needs
to validate and authorize a request; and</li>
<li><strong>proof and audit</strong>, where committed profiles bind each accepted hop to
actor-signed proofs and cumulative committed state for later verification.</li>
</ul>
<t>This document is format-agnostic. JWT deployments use JSON and JWS. CWT
deployments use CBOR and COSE.</t>
</section>

<section anchor="terminology"><name>Terminology</name>
<t>The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;,
&quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; 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.</t>
<t>This document also leverages terminology from OAuth 2.0 Token Exchange
{{!RFC8693}}, the SPICE Architecture {{!I-D.ietf-spice-arch}}, and the RATS
Architecture {{!RFC9334}}.</t>

<ul>
<li><t><strong>Actor</strong>: A workload, service, application component, agent, or other
authenticated entity that receives a token, performs work, and MAY
subsequently act toward another actor.</t>
</li>
<li><t><strong>Current actor</strong>: The authenticated entity presently performing token
exchange.</t>
</li>
<li><t><strong>Presenting actor</strong>: The authenticated actor that presents a
sender-constrained token to a recipient.</t>
</li>
</ul>
<t>Example: when <tt>B</tt> exchanges a token at the Authorization Server, <tt>B</tt> is the
  current actor. When <tt>B</tt> later presents the resulting sender-constrained token
  to <tt>C</tt>, <tt>B</tt> is the presenting actor.</t>

<ul>
<li><t><strong>Recipient</strong>: The actor or resource server identified as the intended target
of an issued token.</t>
</li>
<li><t><strong>Actor chain</strong>: The ordered sequence of actors that have acted so far in one
workflow instance.</t>
</li>
<li><t><strong>Readable chain</strong>: An <tt>ach</tt> value carried in an ordinary token and visible
to downstream recipients.</t>
</li>
<li><t><strong>Committed chain state</strong>: The cumulative cryptographic state that binds
prior accepted chain state to a newly accepted hop.</t>
</li>
<li><t><strong>Step proof</strong>: A profile-defined proof signed by the current actor that
binds that actor's participation to the workflow, prior chain state, and
target context.</t>
</li>
<li><t><strong>Target context</strong>: The canonical representation of the intended audience and
any other target-selection inputs that a profile-defined proof binds to the
next hop.</t>
</li>
<li><t><strong>Workflow identifier (<tt>sid</tt>)</strong>: A stable identifier minted once at workflow
start and retained for the lifetime of the workflow instance.</t>
</li>
<li><t><strong>Cross-domain re-issuance</strong>: A second token exchange performed at another
domain's Authorization Server in order to obtain a local token trusted by the
next recipient, without extending the actor chain.</t>
</li>
<li><t><strong>Continuity</strong>: The property that the inbound token is being presented by the
actor that the chain state indicates should be presenting it.</t>
</li>
<li><t><strong>Append-only processing</strong>: The rule that a newly acting actor is appended to
the prior chain state, without insertion, deletion, reordering, or
modification of prior actors.</t>
</li>
<li><t><strong>Terminal recipient</strong>: A recipient that performs work locally and does not
extend the actor chain further.</t>
</li>
<li><t><strong>Refresh-Exchange</strong>: A token-exchange operation by the same current actor
that refreshes a short-lived transport token without appending the actor
chain, changing the active profile, or generating a new step proof.</t>
</li>
</ul>
</section>

<section anchor="problem-statement"><name>Problem Statement</name>
<t>defines the top-level <tt>act</tt> claim for the current actor and allows
nested prior actors. However, prior nested <tt>act</tt> claims are informational only
for access-control decisions. In multi-hop systems, especially service-to-
service and agentic systems, that is not sufficient.</t>
<t>Consider:</t>

<sourcecode type="text"><![CDATA[User -> Orchestrator -> Planner -> Tool Agent -> Data API
]]></sourcecode>
<t>By the time the request reaches the Data API, the immediate caller may be
visible, but the upstream delegation path is not standardized as a policy input
and is not bound across successive token exchanges in a way that can be
independently validated or audited. This creates several concrete gaps:</t>

<ul spacing="compact">
<li>downstream policy cannot reliably evaluate the full delegation path;</li>
<li>cross-exchange continuity is not standardized;</li>
<li>tampering by an actor and its home AS is not uniformly addressed;</li>
<li>forensic verification of per-hop participation is not standardized; and</li>
<li>ordinary tokens may disclose more prior-actor information than some
deployments are willing to reveal.</li>
</ul>
</section>

<section anchor="relationship-to-rfc-8693-claims"><name>Relationship to RFC 8693 Claims</name>
<t>This specification extends OAuth 2.0 Token Exchange {{!RFC8693}} without
changing the existing meanings of <tt>sub</tt>, <tt>act</tt>, or <tt>may_act</tt>.</t>
<t>The following rules apply:</t>

<ul spacing="compact">
<li><tt>sub</tt> continues to identify the subject of the issued token.</li>
<li><tt>act</tt>, when present, MUST identify the current actor represented by the
issued token.</li>
<li><tt>ach</tt>, when present, is the profile-defined ordered list of actors
that have acted so far in the workflow instance.</li>
<li>Nested prior <tt>act</tt> claims, if present for compatibility or deployment-
specific reasons, remain informational only for access-control purposes,
consistent with {{!RFC8693}}.</li>
<li><tt>may_act</tt>, when present in an inbound token, MAY be used by the accepting
Authorization Server as one input when determining whether the authenticated
current actor is authorized to perform token exchange for the requested
target context.</li>
</ul>
<t>Nothing in this specification redefines the delegation and impersonation
semantics described in {{!RFC8693}}.</t>
</section>

<section anchor="scope-and-model"><name>Scope and Model</name>
<t>This document specifies a family of profiles for representing and validating
actor progression across a linear workflow using OAuth 2.0 Token Exchange.</t>
<t>The base workflow model is linear:</t>

<sourcecode type="text"><![CDATA[A -> B -> C -> D
]]></sourcecode>
<t>The first actor initializes the workflow. Each subsequent actor MAY:</t>

<ol spacing="compact">
<li>validate an inbound token;</li>
<li>perform work; and</li>
<li>exchange that token for a new token representing itself toward the next hop.</li>
</ol>
<t>This document defines five profiles:</t>

<ul spacing="compact">
<li><strong>Asserted Delegation Path</strong>, which carries a readable <tt>ach</tt> and
relies on AS-asserted chain continuity under a non-collusion assumption;</li>
<li><strong>Selectively Disclosed Asserted Delegation Path</strong>, which carries a
selectively disclosed readable <tt>ach</tt> and relies on the issuing AS
for both chain continuity and disclosure policy;</li>
<li><strong>Committed Delegation Path</strong>, which preserves a readable <tt>ach</tt> and
adds actor-signed step proofs plus cumulative committed state;</li>
<li><strong>Commitment-Only Delegation Path</strong>, which omits the readable
<tt>ach</tt> from ordinary tokens and preserves only cumulative committed
state; and</li>
<li><strong>Selectively Disclosed Committed Delegation Path</strong>, which preserves
cumulative committed state and lets the Authorization Server disclose a
recipient-specific ordered subset of prior actors.</li>
</ul>
<t>The five profiles are organized in two branches so that later profiles can be
read as deltas, not as full restatements:</t>

<ul spacing="compact">
<li>the <strong>asserted branch</strong>, rooted at Asserted Delegation Path; and</li>
<li>the <strong>committed branch</strong>, rooted at Committed Delegation Path.</li>
</ul>
<t>Each derived profile inherits all requirements of its branch root except as
modified in that profile. Readers therefore need only read:</t>

<ul spacing="compact">
<li><strong>Asserted Delegation Path</strong> for the asserted branch;</li>
<li><strong>Committed Delegation Path</strong> for the committed branch; and</li>
<li>the concise delta sections for the three derived profiles.</li>
</ul>
<t>The following table is a quick orientation aid.</t>
<table>
<thead>
<tr>
<th>Profile</th>
<th>Readable <tt>ach</tt> in ordinary tokens</th>
<th><tt>achc</tt></th>
<th>Selective disclosure</th>
<th>Next-hop authorization basis</th>
<th>Primary trust/evidence model</th>
</tr>
</thead>

<tbody>
<tr>
<td>Asserted Delegation Path</td>
<td>Full</td>
<td>No</td>
<td>No</td>
<td>Full readable chain</td>
<td>AS-asserted continuity</td>
</tr>

<tr>
<td>Selectively Disclosed Asserted Delegation Path</td>
<td>Disclosed subset</td>
<td>No</td>
<td>Yes</td>
<td>Disclosed readable subset</td>
<td>AS-asserted continuity plus AS disclosure policy</td>
</tr>

<tr>
<td>Committed Delegation Path</td>
<td>Full</td>
<td>Yes</td>
<td>No</td>
<td>Full readable chain</td>
<td>Actor-signed step proofs plus cumulative commitment</td>
</tr>

<tr>
<td>Commitment-Only Delegation Path</td>
<td>No</td>
<td>Yes</td>
<td>No</td>
<td>Presenting actor only</td>
<td>Actor-signed step proofs plus cumulative commitment</td>
</tr>

<tr>
<td>Selectively Disclosed Committed Delegation Path</td>
<td>Disclosed subset</td>
<td>Yes</td>
<td>Yes</td>
<td>Disclosed readable subset plus commitment continuity</td>
<td>Actor-signed step proofs over full chain plus recipient-specific disclosure</td>
</tr>
</tbody>
</table><t>This document does not define branching or fan-out semantics. A single accepted
prior state yields at most one accepted successor state unless a future
specification defines branching behavior. This intentional linearity keeps the
base profiles simple for replay detection, audit reconstruction, and
interoperability.</t>
<t>A deployment that needs parallel downstream work today SHOULD initiate distinct
workflow instances for each branch, each with its own <tt>sid</tt>, rather than
treating multiple successors as one continued linear workflow. This
specification does not define shared-root, branch-merge, or branch-selection
semantics across those separate workflow instances.</t>
</section>

<section anchor="protocol-overview"><name>Protocol Overview</name>

<section anchor="workflow-progression"><name>Workflow Progression</name>
<t>The actor chain advances only when an actor acts. Mere receipt of a token does
not append the recipient.</t>
<t>If <tt>A</tt> calls <tt>B</tt>, and <tt>B</tt> later calls <tt>C</tt>, then:</t>

<ol spacing="compact">
<li><tt>A</tt> begins the workflow and becomes the first acting actor.</li>
<li>When <tt>A</tt> calls <tt>B</tt>, <tt>B</tt> validates a token representing <tt>A</tt>.</li>
<li>When <tt>B</tt> later exchanges that token to call <tt>C</tt>, <tt>B</tt> becomes the next
acting actor.</li>
<li><tt>C</tt> is not appended merely because <tt>C</tt> received a token. <tt>C</tt> is appended
only if <tt>C</tt> later acts toward another hop.</li>
</ol>
<t>A typical same-domain progression looks like this:</t>

<sourcecode type="text"><![CDATA[A                  AS1                 B                  C
|-- bootstrap ----->|                                    |
|<- token T_A ------|                                    |
|------------------------------ present T_A ------------>|
|                                     |
|                                     |-- exchange T_A --> AS1
|                                     |<- token T_B ------|
|------------------------------------------------ present T_B --------->|
]]></sourcecode>
<t>In that example, <tt>B</tt> is the current actor while exchanging <tt>T_A</tt> at <tt>AS1</tt>, and
<tt>B</tt> is the presenting actor when later sending <tt>T_B</tt> to <tt>C</tt>.</t>
</section>

<section anchor="same-domain-and-cross-domain-hops"><name>Same-Domain and Cross-Domain Hops</name>
<t>Within one trust domain, the current actor exchanges its inbound token at its
home Authorization Server, which validates prior state and issues a token for
the next hop.</t>
<t>Across a trust boundary, if the next recipient does not trust the current
Authorization Server directly, the current actor performs a second token
exchange at the next domain's Authorization Server. That second exchange
preserves the already-established chain state and does not append the next
recipient.</t>
<t>A typical cross-domain re-issuance looks like this:</t>

<sourcecode type="text"><![CDATA[B                  AS1                 AS2                 C
|-- exchange ------>|                                     |
|<- token trusted by AS2 --|                              |
|-------------------------- exchange preserved state ---->|
|<------------------------- local token for C ------------|
|------------------------------------------------ present local token -->|
]]></sourcecode>
</section>

<section anchor="trust-boundaries"><name>Trust Boundaries</name>
<t>This specification provides different assurances depending on the selected
profile:</t>

<ul spacing="compact">
<li><strong>Asserted Delegation Path</strong>: the issuing AS signature and chain assertion
are the primary trust anchor.</li>
<li><strong>Selectively Disclosed Asserted Delegation Path</strong>: the issuing AS signature,
chain assertion, and disclosure policy are the primary trust anchors.</li>
<li><strong>Committed Delegation Path</strong>: readable chain state is preserved and each
accepted hop is additionally bound to actor-signed proof and committed state.</li>
<li><strong>Commitment-Only Delegation Path</strong>: readable prior actors are omitted from
ordinary tokens, while committed state and actor-signed proofs remain
available for stronger accountability and later verification.</li>
<li><strong>Selectively Disclosed Committed Delegation Path</strong>: the issuing
Authorization Server reveals only a policy-selected ordered subset of prior
actors to each recipient, while committed state and actor-signed proofs
continue to support later verification.</li>
</ul>
</section>
</section>

<section anchor="common-requirements"><name>Common Requirements</name>

<section anchor="common-token-requirements"><name>Common Token Requirements</name>
<t>Tokens issued under any profile defined by this document:</t>

<ul spacing="compact">
<li>MUST be short-lived;</li>
<li>MUST be sender-constrained to the presenting actor; and</li>
<li><t>MUST contain:</t>

<ul spacing="compact">
<li>a profile identifier claim <tt>achp</tt>;</li>
<li>a workflow identifier claim <tt>sid</tt>;</li>
<li>a unique token identifier claim <tt>jti</tt>;</li>
<li>an audience value <tt>aud</tt>; and</li>
<li>an expiry value <tt>exp</tt>.</li>
</ul></li>
</ul>
<t>Profiles that preserve readable chain state additionally carry <tt>ach</tt>.</t>
<t>Profiles that use selective-disclosure readable chain state carry <tt>ach</tt>
in a selective-disclosure representation appropriate to the token format.</t>
<t>Profiles that preserve committed chain state additionally carry
<tt>achc</tt>.</t>
</section>

<section anchor="workflow-identifier"><name>Workflow Identifier</name>
<t>The <tt>sid</tt> value:</t>

<ul spacing="compact">
<li>MUST be minted once at workflow start by the issuing Authorization Server;</li>
<li>MUST be generated using a CSPRNG with at least 128 bits of entropy;</li>
<li>MUST remain unchanged for the lifetime of that workflow instance; and</li>
<li>MUST NOT be used to signal profile selection.</li>
</ul>
<t>Implementation note: implementers MUST NOT assume that a familiar UUID helper
automatically satisfies the entropy requirement for <tt>sid</tt>. In particular,
standard UUIDv4 provides 122 bits of random entropy and therefore does not by
itself satisfy the requirement stated above.</t>
<t>Profile selection MUST be signaled explicitly using the token request parameter
<tt>actor_chain_profile</tt> and the corresponding token claim
<tt>achp</tt>.</t>
</section>

<section anchor="target-context-requirements"><name>Target Context Requirements</name>
<t>The following normative requirements apply to <tt>target_context</tt>.</t>
<t><tt>target_context</tt> MUST include <tt>aud</tt>.</t>
<t>A deployment MAY additionally include resource identifiers, operation names,
tool identifiers, method names, request classes, or other target-selection
inputs used by local authorization policy.</t>
<t>If no such additional values are available, <tt>target_context</tt> is identical to
<tt>aud</tt>.</t>
<t>Whenever <tt>target_context</tt> is incorporated into a profile-defined signature or
commitment input, it MUST be canonicalized using JCS in JWT deployments and
deterministic CBOR in CWT deployments before hashing or signing.</t>
</section>

<section anchor="sender-constraint"><name>Sender Constraint</name>
<t>A token issued under any profile in this document MUST be sender-constrained to
the actor represented by that token.</t>
<t>A recipient or Authorization Server validating such a token MUST verify the
applicable sender-constrained proof before accepting the token.</t>
<t>Failure of sender-constrained validation MUST cause rejection.</t>
</section>

<section anchor="actor-and-recipient-proof-keys"><name>Actor and Recipient Proof Keys</name>
<t>For committed-chain profiles and for <tt>hop_ack</tt>, any signature used as a
profile-defined proof MUST be generated with an asymmetric key bound to the
authenticated actor or recipient identity by local trust policy.</t>
<t>For a committed-profile step proof, the ActorID represented in the proof, the
key used to sign the proof, and the sender-constrained key used to present the
corresponding token MUST all be bound to the same actor identity. When the same
key is not reused for both functions, the Authorization Server MUST validate an
explicit local binding between the proof-signing key and the sender-constrained
presentation key before accepting the proof.</t>
<t>For <tt>hop_ack</tt>, the recipient ActorID, the key used to sign the acknowledgment,
and any sender-constrained key used by that recipient for the protected
interaction MUST likewise be bound to the same recipient identity.</t>
<t>Shared client secrets MUST NOT be the sole basis for independently verifiable
step proofs or receiver acknowledgments.</t>
<t>A deployment SHOULD reuse the same asymmetric key material used for sender-
constrained token presentation, or another asymmetric key that is
cryptographically bound to the same actor identity.</t>
</section>

<section anchor="intended-recipient-validation"><name>Intended Recipient Validation</name>
<t>When a current actor submits an inbound token as a <tt>subject_token</tt> in token
exchange, the accepting Authorization Server MUST verify that the authenticated
current actor was an intended recipient of that inbound token according to local
audience, resource, or equivalent validation rules.</t>
<t>Possession of an inbound token alone is insufficient.</t>
</section>

<section anchor="replay-and-freshness"><name>Replay and Freshness</name>
<t>Recipients and Authorization Servers MUST enforce replay and freshness checks on
inbound tokens according to local policy.</t>
<t>For profiles that use actor-signed step proofs, the accepting Authorization
Server:</t>

<ul spacing="compact">
<li>MUST detect replay of a previously accepted step proof within its
replay-retention window; and</li>
<li>SHOULD reject a second accepted successor for the same <tt>(sid, prior_state)</tt>
tuple unless a future branching profile is in use.</li>
</ul>
</section>

<section anchor="canonicalization"><name>Canonicalization</name>
<t>All profile-defined signed or hashed inputs MUST use a canonical serialization
defined by this specification.</t>
<t>In JWT/JSON deployments, canonical profile-defined proof payloads MUST be
serialized using JCS {{!RFC8785}}. In CWT/CBOR deployments, they MUST be
serialized using deterministic CBOR encoding as defined in {{!RFC8949}},
Section 4.2.</t>
</section>

<section anchor="actor-identity-representation"><name>Actor Identity Representation</name>
<t>This specification requires a canonical representation for actor identity in
profile-defined chain entries and step proofs.</t>
<t>Each actor identifier MUST be represented as an ActorID structure containing
exactly two members:</t>

<ul spacing="compact">
<li><tt>iss</tt>: the issuer identifier naming the namespace in which the actor subject
value is defined; and</li>
<li><tt>sub</tt>: the subject identifier of the actor within that issuer namespace.</li>
</ul>
<t>For JWT and JSON-based proof payloads, an ActorID is a JSON object with members
<tt>iss</tt> and <tt>sub</tt>, serialized using JCS {{!RFC8785}}.</t>
<t>For CWT and CBOR-based proof payloads, an ActorID is a deterministic CBOR map
with integer label <tt>1</tt> for <tt>iss</tt> and integer label <tt>2</tt> for <tt>sub</tt>.</t>
<t>An ActorID:</t>

<ul spacing="compact">
<li>MUST be stable for equality comparison within a workflow instance;</li>
<li>MUST be bound to the authenticated actor identity used during
sender-constrained token presentation and token exchange;</li>
<li>MUST be compared using exact equality of the pair (<tt>iss</tt>, <tt>sub</tt>); and</li>
<li>SHOULD support pairwise or pseudonymous subject values where deployment
policy allows.</li>
</ul>
<t>Readable-chain profiles carry arrays of ActorID values in <tt>ach</tt>.
Privacy-preserving profiles bind ActorID values only inside step proofs and
related evidence. In examples and formulas, <tt>[A,B]</tt> denotes a readable chain of
ActorID values for actors <tt>A</tt> and <tt>B</tt>.</t>
</section>

<section anchor="artifact-typing"><name>Artifact Typing</name>
<t>JWT-based artifacts defined by this specification MUST use explicit <tt>typ</tt>
values.</t>
<t>The following values are defined:</t>

<ul spacing="compact">
<li><tt>ach-step-proof+jwt</tt></li>
<li><tt>ach-commitment+jwt</tt></li>
<li><tt>ach-hop-ack+jwt</tt></li>
</ul>
<t>Verifiers MUST enforce mutually exclusive validation rules based on artifact
type and MUST NOT accept one artifact type in place of another.</t>
<t>CWT and COSE deployments MUST apply equivalent type discrimination by verifying
the expected artifact class, exact <tt>ctx</tt> value, and artifact-specific payload
structure defined by the relevant binding section of this specification.</t>
</section>

<section anchor="issued-token-type"><name>Issued Token Type</name>
<t>Unless another application profile explicitly states otherwise, tokens issued
under this specification are access tokens.</t>
<t>Token exchange responses MUST use the RFC 8693 token type fields consistently
with the underlying representation and deployment.</t>
</section>

<section anchor="commitment-hash-algorithms"><name>Commitment Hash Algorithms</name>
<t>Committed-chain profiles use a named hash algorithm for construction of
<tt>achc</tt>.</t>
<t>Commitment hash algorithm identifiers are values from the IANA Named
Information Hash Algorithm Registry {{IANA.Hash.Algorithms}}.</t>
<t>Implementations supporting committed-chain profiles MUST implement <tt>sha-256</tt>.
Implementations SHOULD implement <tt>sha-384</tt>.</t>
<t>Every <tt>achc</tt> object and every committed-profile bootstrap
context MUST carry an explicit <tt>halg</tt> value. Verifiers MUST NOT infer or
substitute <tt>halg</tt> when it is absent.</t>
<t>Verifiers MUST enforce a locally configured allow-list of acceptable
commitment hash algorithms and MUST NOT accept algorithm substitution based
solely on attacker-controlled inputs.</t>
</section>

<section anchor="commitment-function"><name>Commitment Function</name>
<t>Committed profiles use <tt>achc</tt> to bind each accepted hop to the
prior accepted state. The commitment hash algorithm is selected once for the
workflow by the issuing Authorization Server during bootstrap and remains fixed
for the lifetime of that workflow instance.</t>
<t>Each <tt>achc</tt> value is a signed commitment object whose payload
contains:</t>

<ul spacing="compact">
<li><tt>ctx</tt>: the context string <tt>actor-chain-commitment-v1</tt>;</li>
<li><tt>sid</tt>: the workflow identifier;</li>
<li><tt>achp</tt>: the active profile identifier;</li>
<li><tt>halg</tt>: the hash algorithm identifier;</li>
<li><tt>prev</tt>: the prior commitment digest, or the bootstrap <tt>initial_chain_seed</tt> at
workflow start;</li>
<li><tt>step_hash</tt>: <tt>Hash_halg(step_proof_bytes)</tt>; and</li>
<li><tt>curr</tt>: <tt>Hash_halg(CanonicalEncode({ctx, sid, achp, halg, prev, step_hash}))</tt>.</li>
</ul>
<t>The <tt>halg</tt> value MUST be a text string naming a hash algorithm from the IANA
Named Information Hash Algorithm Registry {{IANA.Hash.Algorithms}}. This
specification permits only <tt>sha-256</tt> and <tt>sha-384</tt> for
<tt>achc</tt>. Hash algorithms with truncated outputs, including
truncated <tt>sha-256</tt> variants, MUST NOT be used. Other registry values MUST NOT
be used with this specification unless a future Standards Track specification
updates this document.</t>
<t>When a profile-defined proof input refers to a prior
<tt>achc</tt>, the value incorporated into the proof input MUST be
that prior commitment's verified <tt>curr</tt> digest, not the raw serialized
commitment object.</t>
<t>The abstract function used throughout this document is therefore:</t>

<sourcecode type="text"><![CDATA[Commit_AS(prev_digest, step_proof_bytes, halg)
  = AS-signed commitment object over payload {
      ctx,
      sid,
      achp,
      halg,
      prev = prev_digest,
      step_hash = Hash_halg(step_proof_bytes),
      curr = Hash_halg(CanonicalEncode({ctx, sid, achp, halg, prev, step_hash}))
    }
]]></sourcecode>
<t>The exact wire encoding of the signed commitment object is defined in the JWT
and CWT bindings in Appendix A and Appendix B.</t>
</section>

<section anchor="common-cryptographic-operations"><name>Common Cryptographic Operations</name>
<t>The committed profiles use a small number of proof-input templates. This
section defines them once so that profile sections can state only their
profile-specific substitutions.</t>
<t>Let:</t>

<ul spacing="compact">
<li><tt>profile</tt> be the active <tt>achp</tt> value;</li>
<li><tt>sid</tt> be the stable workflow identifier;</li>
<li><tt>prev_state</tt> be either the bootstrap <tt>initial_chain_seed</tt> or the verified
prior commitment digest, as required by the profile;</li>
<li><tt>full_actor_chain_for_hop</tt> be the canonical full readable actor chain for the
hop after appending the authenticated current actor;</li>
<li><tt>TC_next</tt> be the canonical <tt>target_context</tt> for the next hop; and</li>
<li><tt>ActorID(N)</tt> be the authenticated current actor.</li>
</ul>
<t>Symbols such as <tt>TC_B</tt>, <tt>TC_C</tt>, and <tt>TC_next</tt> denote the canonical
<tt>target_context</tt> for the corresponding next hop.</t>
<t>Committed profiles instantiate one of the following proof-input templates:</t>
<t>readable committed chain template:</t>

<sourcecode type="text"><![CDATA[Sign_N(ds || sid || prev_state || full_actor_chain_for_hop || target_context=TC_next)
]]></sourcecode>
<t>private committed chain template:</t>

<sourcecode type="text"><![CDATA[Sign_N(ds || sid || prev_state || actor=ActorID(N) || target_context=TC_next)
]]></sourcecode>
<t>The domain-separation string <tt>ds</tt> is profile-specific:</t>

<ul spacing="compact">
<li><tt>actor-chain-readable-committed-step-sig-v1</tt> for Committed Delegation Path;</li>
<li><tt>actor-chain-private-committed-step-sig-v1</tt> for Commitment-Only Delegation
Path; and</li>
<li><tt>actor-chain-selectively-disclosed-committed-step-sig-v1</tt> for Selectively
Disclosed Committed Delegation Path.</li>
</ul>
<t>In the Selectively Disclosed Committed Delegation Path profile, the readable
value disclosed to the next recipient MAY be a subset, but the proof input
still uses the full canonical chain for that hop.</t>
</section>
</section>

<section anchor="authorization-server-metadata"><name>Authorization Server Metadata</name>
<t>An Authorization Server supporting this specification SHOULD publish metadata
describing supported actor-chain capabilities.</t>
<t>This specification defines the following Authorization Server metadata values:</t>

<ul spacing="compact">
<li><tt>actor_chain_profiles_supported</tt>:
array of supported actor-chain profile identifiers. Each value MUST be the
exact identifier string used both as the <tt>actor_chain_profile</tt> token request
parameter value and as the <tt>achp</tt> token claim value;</li>
<li><tt>actor_chain_commitment_hashes_supported</tt>:
array of supported commitment hash algorithm identifiers;</li>
<li><tt>actor_chain_receiver_ack_supported</tt>:
boolean indicating whether the Authorization Server supports processing and
policy for <tt>hop_ack</tt>; and</li>
<li><tt>actor_chain_refresh_supported</tt>:
boolean indicating whether the Authorization Server supports Refresh-Exchange
processing under this specification.</li>
</ul>
<t>If omitted, clients MUST NOT assume support for any actor-chain profile beyond
out-of-band agreement.</t>
</section>

<section anchor="cross-domain-re-issuance"><name>Cross-Domain Re-Issuance</name>
<t>If the next hop does not trust the current Authorization Server directly, the
current actor MUST perform a second token exchange at the next domain's
Authorization Server.</t>
<t>The cross-domain Authorization Server MUST:</t>

<ul spacing="compact">
<li>validate the inbound token signature and issuer trust according to local
policy;</li>
<li>validate the selected actor-chain profile;</li>
<li>validate the preserved chain-state structure;</li>
<li>preserve <tt>achp</tt>;</li>
<li>preserve <tt>sid</tt>;</li>
<li>preserve <tt>ach</tt>, if present;</li>
<li>preserve <tt>achc</tt>, if present, exactly as verified;</li>
<li>continue to represent the same current actor; and</li>
<li>NOT append the next recipient.</li>
</ul>
<t>The cross-domain Authorization Server MAY mint a new local <tt>jti</tt>, apply a new
local expiry, change token format or envelope, and add local trust or policy
claims. It MUST NOT alter the verified preserved chain state.</t>
</section>

<section anchor="refresh-exchange"><name>Refresh-Exchange</name>
<t>A current actor MAY use token exchange to refresh a short-lived transport token
without appending the actor chain or regenerating a step proof.</t>
<t>A Refresh-Exchange request MUST include:</t>

<ul spacing="compact">
<li><tt>actor_chain_refresh=true</tt>;</li>
<li>the current inbound actor-chain token as the RFC 8693 <tt>subject_token</tt>; and</li>
<li>the same authenticated current actor that is represented by that token.</li>
</ul>
<t>A Refresh-Exchange request MUST NOT broaden the active profile, represented
actor identity, readable chain state, committed chain state, or target context.
The requested target context MUST be identical to, or narrower than, the target
context already represented by the inbound token according to local policy.</t>
<t>When processing Refresh-Exchange, the Authorization Server MUST:</t>

<ul spacing="compact">
<li>validate the inbound token and the identity of the current actor;</li>
<li>verify sender constraint and intended-recipient semantics as applicable;</li>
<li>verify that the request does not append the chain, alter preserved chain
state, or broaden target context; and</li>
<li>issue a replacement token with a new <tt>jti</tt> and refreshed <tt>exp</tt>.</li>
</ul>
<t>For Refresh-Exchange, the Authorization Server MUST preserve <tt>sid</tt>,
<tt>achp</tt>, <tt>ach</tt>, and <tt>achc</tt>, if
present. A new step proof MUST NOT be required, and a new commitment object
MUST NOT be created.</t>
<t>A Refresh-Exchange MAY rotate the sender-constrained presentation key only if
the actor provides a key-transition proof that binds the new presentation key
to the same <tt>sid</tt> and ActorID under local policy, and the Authorization Server
verifies and records that proof. Such proof MAY be satisfied by continuity
mechanisms provided by the sender-constrained binding in use or by another
locally trusted proof-of-possession transition method. Otherwise, the sender-
constrained key binding MUST be preserved. Historical step proofs remain bound
to the keys used when those proofs were created and MUST be verified against
those historical bindings, not against a later rotated key.</t>
<t>A recipient or coordinating component MUST treat a token obtained by
Refresh-Exchange as representing the same accepted chain state as the inbound
token from which it was refreshed. If a sender-constrained key transition
occurred, recipients still validate historical step proofs against the keys
bound when those proofs were produced and rely on Authorization-Server records
or other retained evidence for the key-transition event itself.</t>
</section>

<section anchor="error-handling"><name>Error Handling</name>
<t>Token exchange errors in this specification build on OAuth 2.0 and OAuth 2.0
Token Exchange.</t>
<t>An Authorization Server processing a token exchange request applies the
following mapping:</t>
<table>
<thead>
<tr>
<th>OAuth error code</th>
<th>Triggering condition</th>
</tr>
</thead>

<tbody>
<tr>
<td><tt>invalid_request</tt></td>
<td>Malformed or missing profile-defined parameters, malformed bootstrap context, malformed ActorID values, malformed commitment objects, or unsupported profile bindings</td>
</tr>

<tr>
<td><tt>invalid_target</tt></td>
<td>The requested audience, target context, or recipient is not permitted or not supported</td>
</tr>

<tr>
<td><tt>invalid_grant</tt></td>
<td>The <tt>subject_token</tt> fails validation, sender-constrained verification fails, the intended-recipient check fails, continuity fails at token exchange, replay or freshness checks fail, <tt>actor_chain_step_proof</tt> verification fails, or the submitted prior state is inconsistent with the claimed profile state</td>
</tr>
</tbody>
</table><t>Recipients and Authorization Servers MUST return protocol-appropriate error
signals for authentication, authorization, profile-validation, and continuity
failures.</t>
<t>In HTTP deployments, this typically maps to 400-series status codes and OAuth-
appropriate error values. In non-HTTP deployments, functionally equivalent
protocol-native error signaling MUST be used.</t>
<t>Error responses and logs MUST NOT disclose undisclosed prior actors, full step
proofs, request-context digests, or other sensitive proof material unless the
deployment explicitly requires such disclosure for diagnostics.</t>
</section>

<section anchor="common-validation-procedures"><name>Common Validation Procedures</name>

<section anchor="recipient-validation-of-an-inbound-token"><name>Recipient Validation of an Inbound Token</name>
<t>Unless a profile states otherwise, a recipient validating an inbound actor-chain
token MUST verify:</t>

<ul spacing="compact">
<li>token signature;</li>
<li>issuer trust;</li>
<li>audience and target-context consistency according to local policy;</li>
<li>expiry;</li>
<li>sender constraint; and</li>
<li>replay and freshness state.</li>
</ul>
</section>

<section anchor="authorization-server-validation-of-token-exchange"><name>Authorization Server Validation of Token Exchange</name>
<t>Unless a profile states otherwise, an Authorization Server processing a token
exchange under this specification MUST verify:</t>

<ul spacing="compact">
<li>the inbound <tt>subject_token</tt>;</li>
<li>the identity of the current actor;</li>
<li>replay and freshness constraints;</li>
<li>intended-recipient semantics for the inbound token; and</li>
<li>authorization to act for the requested target context.</li>
</ul>
</section>

<section anchor="current-actor-validation-of-a-returned-token"><name>Current-Actor Validation of a Returned Token</name>
<t>Unless a profile states otherwise, a current actor validating a returned token
from token exchange MUST verify the token signature, profile identifier, and
any profile-specific append-only or commitment checks before presenting that
token to the next hop.</t>
</section>
</section>

<section anchor="profiles"><name>Profiles</name>
<t>The profile selection table appears earlier in &quot;Scope and Model&quot;. The sections
below define the asserted branch root, the committed branch root, and the
derived profiles that inherit from those roots.</t>
</section>

<section anchor="asserted-delegation-path-profile"><name>Asserted Delegation Path Profile</name>

<section anchor="profile-identifier"><name>Profile Identifier</name>
<t>The profile identifier string for this profile is
<tt>asserted-delegation-path</tt>. It is used as the <tt>actor_chain_profile</tt> token
request parameter value and as the <tt>achp</tt> token claim value.</t>
</section>

<section anchor="objective"><name>Objective</name>
<t>The Asserted Delegation Path profile extends token exchange by carrying a
readable <tt>ach</tt> and requiring chain-continuity validation by both the
current actor and the issuing Authorization Server at each hop.</t>
</section>

<section anchor="security-model"><name>Security Model</name>
<t>This profile provides hop-by-hop readable chain integrity based on issuer-
asserted chain state and continuity checks.</t>
<t>This profile assumes that an actor does not collude with its home Authorization
Server.</t>
</section>

<section anchor="bootstrap"><name>Bootstrap</name>
<t>At workflow start, actor <tt>A</tt> MUST request a token from <tt>AS1</tt> with:</t>

<ul spacing="compact">
<li><tt>actor_chain_profile=asserted-delegation-path</tt></li>
<li><tt>audience=B</tt></li>
</ul>
<t>If <tt>AS1</tt> accepts the request, <tt>AS1</tt> MUST issue <tt>T_A</tt> containing at least:</t>

<ul spacing="compact">
<li><tt>achp=asserted-delegation-path</tt></li>
<li><tt>ach=[A]</tt></li>
<li><tt>sid</tt></li>
<li><tt>jti</tt></li>
<li><tt>aud=B</tt></li>
<li><tt>exp</tt></li>
</ul>
</section>

<section anchor="hop-processing"><name>Hop Processing</name>
<t>When <tt>A</tt> calls <tt>B</tt>, <tt>A</tt> MUST present <tt>T_A</tt> to <tt>B</tt>.</t>
<t><tt>B</tt> MUST perform recipient validation as described in
&quot;Recipient Validation of an Inbound Token&quot;.</t>
<t><tt>B</tt> MUST extract the verified <tt>ach</tt> and verify that its last actor is
<tt>A</tt>.</t>
<t>If that continuity check fails, <tt>B</tt> MUST reject the request.</t>
</section>

<section anchor="token-exchange"><name>Token Exchange</name>
<t>To call <tt>C</tt>, <tt>B</tt> MUST submit <tt>T_A</tt> to <tt>AS1</tt> as the RFC 8693 <tt>subject_token</tt>.</t>
<t><tt>AS1</tt> MUST perform token-exchange validation as described in
&quot;Authorization Server Validation of Token Exchange&quot;.</t>
<t><tt>AS1</tt> MUST read the prior chain from <tt>T_A</tt>, append <tt>B</tt>, and issue <tt>T_B</tt>
containing at least:</t>

<ul spacing="compact">
<li><tt>achp=asserted-delegation-path</tt></li>
<li><tt>ach=[A,B]</tt></li>
<li><tt>sid</tt></li>
<li><tt>jti</tt></li>
<li><tt>aud=C</tt></li>
<li><tt>exp</tt></li>
</ul>
</section>

<section anchor="returned-token-validation"><name>Returned Token Validation</name>
<t>Upon receipt of <tt>T_B</tt>, <tt>B</tt> MUST perform current-actor returned-token
validation as described in &quot;Current-Actor Validation of a Returned Token&quot;.</t>
<t><tt>B</tt> MUST verify that <tt>T_B.ach</tt> is exactly the previously verified chain
from <tt>T_A</tt> with <tt>B</tt> appended.</t>
<t>If that append-only check fails, <tt>B</tt> MUST reject <tt>T_B</tt>.</t>
</section>

<section anchor="next-hop-validation"><name>Next-Hop Validation</name>
<t>Upon receipt of the final B-token, <tt>C</tt> MUST perform recipient validation as
described in &quot;Recipient Validation of an Inbound Token&quot;.</t>
<t><tt>C</tt> MUST extract the verified <tt>ach</tt> and use it for authorization
decisions.</t>
</section>

<section anchor="security-result"><name>Security Result</name>
<t>Under the non-collusion assumption, prior actors MUST NOT be silently inserted,
removed, reordered, or altered during token exchange.</t>
</section>

<section anchor="limits"><name>Limits</name>
<t>This profile does not address tampering by a colluding actor and its home
Authorization Server.</t>
<t>This profile does not by itself address malicious application payloads.</t>
<t>This profile does not by itself prevent confused-deputy behavior.</t>
</section>
</section>

<section anchor="selectively-disclosed-asserted-delegation-path-profile"><name>Selectively Disclosed Asserted Delegation Path Profile</name>

<section anchor="profile-identifier-1"><name>Profile Identifier</name>
<t>The profile identifier string for this profile is
<tt>selectively-disclosed-asserted-delegation-path</tt>. It is used as the
<tt>actor_chain_profile</tt> token request parameter value and as the <tt>achp</tt> token
claim value.</t>
</section>

<section anchor="objective-1"><name>Objective</name>
<t>This profile inherits the Asserted Delegation Path profile and changes only the
visibility of the readable chain: the issuing Authorization Server MAY disclose
only a recipient-specific ordered subset of the canonical full chain.</t>
</section>

<section anchor="inheritance-and-security-model"><name>Inheritance and Security Model</name>
<t>Except as modified below, all requirements of the Asserted Delegation Path
profile apply.</t>
<t>The disclosed <tt>ach</tt> seen by a recipient MUST be an ordered subsequence
of the canonical full chain for that hop and MUST include the current actor as
its last element.</t>
<t>A recipient MUST treat undisclosed prior actors as unavailable and MUST NOT
infer adjacency, absence, or exact chain length from the disclosed subset
alone.</t>
<t>This profile relies on the issuing Authorization Server for hidden prior-chain
continuity and disclosure policy. It does not provide the step-proof-based
accountability or cumulative commitment state of the committed profiles.</t>
</section>

<section anchor="modified-bootstrap-and-issuance"><name>Modified Bootstrap and Issuance</name>
<t>At bootstrap and at each later exchange, wherever the Asserted Delegation Path
profile would issue a token containing a readable <tt>ach</tt>, this profile
MUST instead issue a selectively disclosable <tt>ach</tt> for the intended
recipient.</t>
<t>If the token format requires separate disclosure artifacts, the issuing
Authorization Server MUST return the artifacts needed for that recipient to
recover the disclosed <tt>ach</tt>.</t>
</section>

<section anchor="modified-hop-processing-and-validation"><name>Modified Hop Processing and Validation</name>
<t>Where the Asserted Delegation Path profile requires presentation or validation
of a readable <tt>ach</tt>, this profile instead requires presentation and
validation of the selectively disclosed chain and the applicable selective-
disclosure proof.</t>
<t>The current recipient and the current actor MUST verify that the last disclosed
actor is the presenting actor for the inbound token or, for a returned token,
the current actor that requested exchange.</t>
<t>Unlike the Asserted Delegation Path profile, the current actor and downstream
recipient do not independently validate the hidden undisclosed portion of the
prior chain. They validate only the disclosed subset they receive.</t>
</section>

<section anchor="next-hop-authorization"><name>Next-Hop Authorization</name>
<t>A recipient MAY use the verified disclosed <tt>ach</tt> for authorization
decisions.</t>
<t>A recipient MUST use only the disclosed <tt>ach</tt> for authorization and
MUST treat undisclosed prior actors as unavailable.</t>
</section>

<section anchor="security-result-1"><name>Security Result</name>
<t>Under the non-collusion assumption, silent insertion, removal, reordering, or
alteration of the disclosed chain seen by a recipient is prevented with respect
to what the issuing Authorization Server asserted for that recipient.</t>
</section>

<section anchor="limits-1"><name>Limits</name>
<t>This profile does not let the current actor or a downstream recipient
independently validate hidden prior actors that were not disclosed to them.</t>
<t>This profile does not provide step-proof-based accountability or cumulative
commitment-based auditability.</t>
<t>This profile does not by itself address malicious application payloads.</t>
<t>This profile does not by itself prevent confused-deputy behavior.</t>
</section>
</section>

<section anchor="committed-delegation-path-profile"><name>Committed Delegation Path Profile</name>

<section anchor="profile-identifier-2"><name>Profile Identifier</name>
<t>The profile identifier string for this profile is
<tt>committed-delegation-path</tt>. It is used as the <tt>actor_chain_profile</tt> token
request parameter value and as the <tt>achp</tt> token claim value.</t>
</section>

<section anchor="objective-2"><name>Objective</name>
<t>The Committed Delegation Path profile builds on the Asserted Delegation Path
profile by adding per-hop actor-signed step proofs and cumulative committed
state, while preserving a readable <tt>ach</tt> for downstream authorization.</t>
</section>

<section anchor="security-model-1"><name>Security Model</name>
<t>This profile preserves readable chain-based authorization and provides stronger
accountability and non-repudiation than the Asserted Delegation Path profile.</t>
<t>This profile does not guarantee inline prevention of every invalid token that
could be issued by a colluding actor and its home Authorization Server.</t>
<t>The evidentiary value of this profile depends on retention or discoverability of
step proofs, exchange records, and associated verification material.</t>
</section>

<section anchor="bootstrap-1"><name>Bootstrap</name>

<section anchor="bootstrap-context-request"><name>Bootstrap Context Request</name>
<t>At workflow start, actor <tt>A</tt> MUST request bootstrap context from <tt>AS1</tt> with:</t>

<ul spacing="compact">
<li><tt>actor_chain_profile=committed-delegation-path</tt></li>
<li><tt>audience=B</tt></li>
</ul>
<t><tt>AS1</tt> selects <tt>halg</tt> for the workflow according to local policy and the
supported values advertised in Authorization Server metadata.</t>
<t><tt>AS1</tt> MUST generate:</t>

<ul spacing="compact">
<li><tt>sid</tt>;</li>
<li><tt>halg</tt>; and</li>
<li><tt>initial_chain_seed</tt>.</li>
</ul>
<t>The <tt>halg</tt> value in the bootstrap context MUST be either <tt>sha-256</tt> or
<tt>sha-384</tt> and MUST remain fixed for the lifetime of the workflow instance.</t>
<t><tt>initial_chain_seed</tt> MUST be derived as:</t>

<sourcecode type="text"><![CDATA[Hash_halg("actor-chain-readable-committed-init" || sid)
]]></sourcecode>
<t><tt>AS1</tt> MUST return bootstrap context containing at least:</t>

<ul spacing="compact">
<li><tt>sid</tt>;</li>
<li><tt>halg</tt>;</li>
<li><tt>initial_chain_seed</tt>;</li>
<li><tt>audience=B</tt>; and</li>
<li>a short expiry.</li>
</ul>
<t>The bootstrap context MUST be integrity protected by <tt>AS1</tt> and MUST be single
use.</t>
</section>

<section anchor="initial-actor-step-proof"><name>Initial Actor Step Proof</name>
<t><tt>A</tt> MUST construct:</t>

<ul spacing="compact">
<li><tt>ach=[A]</tt></li>
</ul>
<t><tt>A</tt> MUST compute a step proof:</t>

<sourcecode type="text"><![CDATA[chain_sig_A = Sign_A("actor-chain-readable-committed-step-sig-v1" || sid || initial_chain_seed || [A] || target_context=TC_B)
]]></sourcecode>
<t>using canonical encoding.</t>
<t><tt>A</tt> MUST submit a token request containing:</t>

<ul spacing="compact">
<li><tt>actor_chain_profile=committed-delegation-path</tt>;</li>
<li><tt>actor_chain_step_proof=chain_sig_A</tt>; and</li>
<li>the <tt>AS1</tt> bootstrap context.</li>
</ul>
</section>

<section anchor="bootstrap-issuance"><name>Bootstrap Issuance</name>
<t><tt>AS1</tt> MUST verify:</t>

<ul spacing="compact">
<li>the bootstrap context;</li>
<li>the identity of <tt>A</tt>; and</li>
<li>the validity of <tt>chain_sig_A</tt>.</li>
</ul>
<t>If verification succeeds, <tt>AS1</tt> MUST compute:</t>

<sourcecode type="text"><![CDATA[achc = Commit_AS1(initial_chain_seed, chain_sig_A)
]]></sourcecode>
<t><tt>AS1</tt> MUST then issue <tt>T_A</tt> containing at least:</t>

<ul spacing="compact">
<li><tt>achp=committed-delegation-path</tt></li>
<li><tt>ach=[A]</tt></li>
<li><tt>achc</tt></li>
<li><tt>sid</tt></li>
<li><tt>jti</tt></li>
<li><tt>aud=B</tt></li>
<li><tt>exp</tt></li>
</ul>
</section>
</section>

<section anchor="hop-processing-1"><name>Hop Processing</name>
<t>When <tt>A</tt> calls <tt>B</tt>, <tt>A</tt> MUST present <tt>T_A</tt> to <tt>B</tt>.</t>
<t><tt>B</tt> MUST verify:</t>

<ul spacing="compact">
<li>token signature;</li>
<li>issuer trust;</li>
<li>audience;</li>
<li>expiry;</li>
<li>sender constraint; and</li>
<li>replay and freshness state.</li>
</ul>
<t><tt>B</tt> MUST extract:</t>

<ul spacing="compact">
<li><tt>ach</tt>;</li>
<li><tt>achc</tt>; and</li>
<li><tt>sid</tt>.</li>
</ul>
<t><tt>B</tt> MUST verify that the last actor in the readable chain is <tt>A</tt>.</t>
<t>If that continuity check fails, <tt>B</tt> MUST reject the request.</t>
</section>

<section anchor="token-exchange-1"><name>Token Exchange</name>
<t>To call <tt>C</tt>, <tt>B</tt> MUST:</t>

<ul spacing="compact">
<li>construct <tt>new_actor_chain=[A,B]</tt>; and</li>
<li>set <tt>prior_commitment_digest</tt> to the verified <tt>curr</tt> value extracted from <tt>T_A.achc</tt>.</li>
</ul>
<t><tt>B</tt> MUST compute:</t>

<sourcecode type="text"><![CDATA[chain_sig_B = Sign_B("actor-chain-readable-committed-step-sig-v1" || sid || prior_commitment_digest || [A,B] || target_context=TC_C)
]]></sourcecode>
<t>using canonical encoding.</t>
<t><tt>B</tt> MUST submit to <tt>AS1</tt>:</t>

<ul spacing="compact">
<li><tt>T_A</tt> as the RFC 8693 <tt>subject_token</tt>; and</li>
<li><tt>actor_chain_step_proof=chain_sig_B</tt>.</li>
</ul>
<t><tt>AS1</tt> MUST verify:</t>

<ul spacing="compact">
<li><tt>T_A</tt>;</li>
<li>the identity of <tt>B</tt>;</li>
<li>replay and freshness constraints;</li>
<li>that <tt>B</tt> was an intended recipient of the inbound <tt>subject_token</tt>;</li>
<li>that <tt>B</tt> is authorized to act for the requested target context; and</li>
<li><t>that <tt>chain_sig_B</tt> binds:</t>

<ul spacing="compact">
<li>the same <tt>sid</tt>;</li>
<li>the same prior commitment;</li>
<li>the reconstructed <tt>new_actor_chain</tt>; and</li>
<li>the requested target context <tt>TC_C</tt>.</li>
</ul></li>
</ul>
<t>If verification succeeds, <tt>AS1</tt> MUST compute:</t>

<sourcecode type="text"><![CDATA[achc = Commit_AS1(prior_commitment_digest, chain_sig_B)
]]></sourcecode>
<t><tt>AS1</tt> MUST issue <tt>T_B</tt> containing at least:</t>

<ul spacing="compact">
<li><tt>achp=committed-delegation-path</tt></li>
<li><tt>ach=[A,B]</tt></li>
<li><tt>achc</tt></li>
<li><tt>sid</tt></li>
<li><tt>jti</tt></li>
<li><tt>aud=C</tt></li>
<li><tt>exp</tt></li>
</ul>
</section>

<section anchor="returned-token-validation-1"><name>Returned Token Validation</name>
<t>Upon receipt of <tt>T_B</tt>, <tt>B</tt> MUST verify the token signature and profile fields.</t>
<t><tt>B</tt> MUST verify that:</t>

<ul spacing="compact">
<li>the returned readable chain is exactly <tt>[A,B]</tt>; and</li>
<li>the returned <tt>achc</tt> equals
<tt>Commit_AS1(prior_commitment_digest, chain_sig_B)</tt>.</li>
</ul>
<t>If either check fails, <tt>B</tt> MUST reject <tt>T_B</tt>.</t>
</section>

<section anchor="next-hop-validation-1"><name>Next-Hop Validation</name>
<t>Upon receipt of the final B-token, <tt>C</tt> MUST verify:</t>

<ul spacing="compact">
<li>issuer trust;</li>
<li>token signature;</li>
<li>audience;</li>
<li>expiry;</li>
<li>sender constraint; and</li>
<li>replay and freshness state.</li>
</ul>
<t><tt>C</tt> MUST extract:</t>

<ul spacing="compact">
<li><tt>ach</tt>;</li>
<li><tt>achc</tt>; and</li>
<li><tt>sid</tt>.</li>
</ul>
<t><tt>C</tt> MUST use the readable <tt>ach</tt> for authorization decisions.</t>
</section>

<section anchor="attack-handling"><name>Attack Handling</name>
<t>A claim that actor <tt>V</tt> participated in the chain MUST fail unless a valid step
proof for <tt>V</tt> can be produced and verified against the corresponding prior
committed state and <tt>sid</tt>.</t>
<t>If an actor is omitted from a later readable chain, that omitted actor MAY prove
prior participation by presenting:</t>

<ul spacing="compact">
<li>an earlier token showing the prior chain state; and</li>
<li>the corresponding committed state and verifiable step proof, or an immutable
Authorization-Server exchange record.</li>
</ul>
<t>A denial of participation by actor <tt>X</tt> MUST fail if a valid step proof for <tt>X</tt>
is available and verifies.</t>
</section>

<section anchor="security-result-2"><name>Security Result</name>
<t>This profile preserves readable chain-based authorization while making tampering
materially easier to detect, prove, and audit.</t>
</section>

<section anchor="limits-2"><name>Limits</name>
<t>This profile does not by itself solve malicious application payloads.</t>
<t>This profile does not by itself solve confused-deputy behavior.</t>
<t>This profile does not by itself solve privacy minimization or workflow
branching.</t>
</section>
</section>

<section anchor="commitment-only-delegation-path-profile"><name>Commitment-Only Delegation Path Profile</name>

<section anchor="profile-identifier-3"><name>Profile Identifier</name>
<t>The profile identifier string for this profile is
<tt>commitment-only-delegation-path</tt>. It is used as the <tt>actor_chain_profile</tt>
token request parameter value and as the <tt>achp</tt> token claim value.</t>
</section>

<section anchor="objective-3"><name>Objective</name>
<t>This profile inherits the Committed Delegation Path profile and removes the
readable <tt>ach</tt> from ordinary tokens, leaving only cumulative committed
state and the verified presenting actor visible at the next hop.</t>
</section>

<section anchor="inheritance-and-security-model-1"><name>Inheritance and Security Model</name>
<t>Except as modified below, all requirements of the Committed Delegation Path
profile apply.</t>
<t>This profile preserves sender-constrained current-actor continuity and
cumulative committed state, but ordinary recipients see only an opaque
commitment object and not a readable prior-actor path.</t>
<t>This profile does not preserve readable prior-actor authorization at downstream
hops. Prior-actor integrity is ordinarily verifiable only by the issuing
Authorization Server or an auditor with access to retained step proofs or
exchange records.</t>
</section>

<section anchor="modified-bootstrap-and-issuance-1"><name>Modified Bootstrap and Issuance</name>
<t>This profile uses the same committed bootstrap pattern as the Committed
Delegation Path profile with these substitutions:</t>

<ul spacing="compact">
<li>the profile value is <tt>commitment-only-delegation-path</tt>;</li>
<li><tt>initial_chain_seed</tt> MUST be derived as shown below; and</li>
<li>each step proof MUST bind actor identity instead of a readable full chain.</li>
</ul>

<sourcecode type="text"><![CDATA[Hash_halg("actor-chain-private-committed-init" || sid)
]]></sourcecode>
<t>The initial actor therefore computes:</t>

<sourcecode type="text"><![CDATA[chain_sig_A = Sign_A("actor-chain-private-committed-step-sig-v1" || sid || initial_chain_seed || actor=ActorID(A) || target_context=TC_B)
]]></sourcecode>
<t>At each later hop, the acting actor computes:</t>

<sourcecode type="text"><![CDATA[chain_sig_N = Sign_N("actor-chain-private-committed-step-sig-v1" || sid || prior_commitment_digest || actor=ActorID(N) || target_context=TC_next)
]]></sourcecode>
<t>The issuing Authorization Server MUST verify the same committed-state
continuity checks as in the Committed Delegation Path profile, using actor
identity in place of the readable full chain.</t>
<t>Tokens issued under this profile MUST contain <tt>achc</tt>, <tt>sid</tt>,
<tt>jti</tt>, <tt>aud</tt>, and <tt>exp</tt>, and MUST NOT contain a readable <tt>ach</tt>.</t>
</section>

<section anchor="modified-hop-processing-and-validation-1"><name>Modified Hop Processing and Validation</name>
<t>Where the Committed Delegation Path profile would validate a readable
<tt>ach</tt>, this profile instead validates only:</t>

<ul spacing="compact">
<li>the presenting actor;</li>
<li><tt>achc</tt>; and</li>
<li><tt>sid</tt>.</li>
</ul>
<t>The current recipient and the next-hop recipient MUST verify that the token is
being presented by the current actor.</t>
<t>The current actor validating a returned token MUST verify only that the returned
commitment equals the expected <tt>Commit_AS(prior_commitment_digest, chain_sig)</tt>.</t>
<t>A downstream recipient MUST use the verified presenting actor, not prior actors,
for authorization decisions.</t>
<t>A downstream recipient MUST NOT infer the identities or number of prior actors
from <tt>achc</tt> alone.</t>
</section>

<section anchor="attack-handling-1"><name>Attack Handling</name>
<t>The committed-profile attack-handling properties still apply, but omission,
insertion, or reordering of prior actors will ordinarily be detected only by
the issuing Authorization Server or by later audit, not by ordinary downstream
recipients inline.</t>
</section>

<section anchor="security-result-3"><name>Security Result</name>
<t>This profile reduces ordinary-token disclosure and token size while preserving
per-hop continuation proofs at the acting hop and cumulative committed state
across hops.</t>
</section>

<section anchor="limits-3"><name>Limits</name>
<t>This profile does not preserve readable prior-actor authorization at downstream
hops.</t>
<t>This profile does not by itself allow downstream hops to detect omission,
insertion, or reordering of prior actors inline once readable disclosure is
removed.</t>
<t>This profile does not hide prior actors from the Authorization Server that
processes token exchange.</t>
<t>This profile does not by itself solve malicious application payloads.</t>
<t>This profile does not by itself solve confused-deputy behavior.</t>
<t>This profile does not by itself solve workflow branching.</t>
</section>
</section>

<section anchor="selectively-disclosed-committed-delegation-path-profile"><name>Selectively Disclosed Committed Delegation Path Profile</name>

<section anchor="profile-identifier-4"><name>Profile Identifier</name>
<t>The profile identifier string for this profile is
<tt>selectively-disclosed-committed-delegation-path</tt>. It is used as the
<tt>actor_chain_profile</tt> token request parameter value and as the <tt>achp</tt> token
claim value.</t>
</section>

<section anchor="objective-4"><name>Objective</name>
<t>This profile inherits the Committed Delegation Path profile and changes only
what ordinary recipients see: the issuing Authorization Server MAY disclose
only a recipient-specific ordered subset of the full readable chain, while step
proofs and commitments continue to bind the full canonical chain.</t>
</section>

<section anchor="inheritance-and-security-model-2"><name>Inheritance and Security Model</name>
<t>Except as modified below, all requirements of the Committed Delegation Path
profile apply.</t>
<t>The disclosed <tt>ach</tt> seen by a recipient MUST be an ordered subsequence
of the canonical full chain for that hop and MUST include the current actor as
its last element.</t>
<t>Step proofs and <tt>achc</tt> values MUST be computed over the full
canonical chain for the hop, not over the later disclosed subset.</t>
<t>A recipient MUST treat undisclosed prior actors as unavailable and MUST NOT
infer adjacency, absence, or exact chain length from the disclosed subset
alone.</t>
</section>

<section anchor="modified-bootstrap-and-issuance-2"><name>Modified Bootstrap and Issuance</name>
<t>This profile uses the same committed bootstrap pattern as the Committed
Delegation Path profile with these substitutions:</t>

<ul spacing="compact">
<li>the profile value is <tt>selectively-disclosed-committed-delegation-path</tt>;</li>
<li><tt>initial_chain_seed</tt> MUST be derived as shown below; and</li>
<li>each step proof MUST use the profile-specific domain-separation string
<tt>&quot;actor-chain-selectively-disclosed-committed-step-sig-v1&quot;</tt> while still
binding the full canonical readable chain for the hop.</li>
</ul>

<sourcecode type="text"><![CDATA[Hash_halg("actor-chain-selectively-disclosed-committed-init" || sid)
]]></sourcecode>
<t>The initial actor therefore computes:</t>

<sourcecode type="text"><![CDATA[chain_sig_A = Sign_A("actor-chain-selectively-disclosed-committed-step-sig-v1" || sid || initial_chain_seed || [A] || target_context=TC_B)
]]></sourcecode>
<t>At each later hop, the acting actor computes:</t>

<sourcecode type="text"><![CDATA[chain_sig_N = Sign_N("actor-chain-selectively-disclosed-committed-step-sig-v1" || sid || prior_commitment_digest || full_actor_chain_for_hop || target_context=TC_next)
]]></sourcecode>
<t>The issuing Authorization Server MUST verify the same full-chain committed-state
continuity checks as in the Committed Delegation Path profile.</t>
<t>Where the Committed Delegation Path profile would issue a token containing a
readable full <tt>ach</tt>, this profile MUST instead issue a selectively
disclosable <tt>ach</tt> for the intended recipient together with any required
disclosure artifacts.</t>
<t>Tokens issued under this profile MUST also contain <tt>achc</tt>,
<tt>sid</tt>, <tt>jti</tt>, <tt>aud</tt>, and <tt>exp</tt>.</t>
</section>

<section anchor="modified-hop-processing-and-validation-2"><name>Modified Hop Processing and Validation</name>
<t>Where the Committed Delegation Path profile would present or validate a readable
full <tt>ach</tt>, this profile instead presents and validates the disclosed
<tt>ach</tt> and the applicable selective-disclosure proof.</t>
<t>The current recipient and the next-hop recipient MUST verify that the last
disclosed actor is the presenting actor.</t>
<t>The current actor validating a returned token MUST verify:</t>

<ul spacing="compact">
<li>the returned <tt>achc</tt>;</li>
<li>that the returned disclosure material yields a disclosed <tt>ach</tt> whose
last actor is that current actor; and</li>
<li>that the disclosed chain is an ordered subsequence of the full canonical
chain that the current actor signed for that hop.</li>
</ul>
<t>A recipient MAY use the verified disclosed <tt>ach</tt> for authorization
decisions, but MUST use only the disclosed subset and MUST treat undisclosed
prior actors as unavailable.</t>
</section>

<section anchor="attack-handling-2"><name>Attack Handling</name>
<t>The committed-profile attack-handling properties still apply to the full
canonical chain.</t>
<t>Different recipients MAY receive different valid disclosed subsets derived from
the same canonical full chain according to local disclosure policy. That alone
does not constitute an integrity failure.</t>
<t>An actor omitted from a disclosed chain MAY still prove prior participation by
presenting the corresponding step proof or immutable Authorization-Server
exchange record for the canonical full chain.</t>
</section>

<section anchor="security-result-4"><name>Security Result</name>
<t>This profile preserves current-actor continuity, cumulative committed state, and
recipient-specific limited readable authorization while keeping the full
workflow progression reconstructable from committed proof state.</t>
</section>

<section anchor="limits-4"><name>Limits</name>
<t>This profile does not preserve full readable prior-actor authorization at
downstream hops.</t>
<t>This profile does not hide prior actors from the Authorization Server that
processes token exchange.</t>
<t>This profile does not by itself solve malicious application payloads.</t>
<t>This profile does not by itself solve confused-deputy behavior.</t>
<t>This profile does not by itself solve workflow branching.</t>
</section>
</section>

<section anchor="optional-receiver-acknowledgment-extension"><name>Optional Receiver Acknowledgment Extension</name>
<t>A recipient MAY produce a receiver acknowledgment artifact, called <tt>hop_ack</tt>,
for an inbound actor-chain token. This OPTIONAL extension does not alter chain
progression semantics.</t>
<t>A valid <tt>hop_ack</tt> proves that the recipient accepted responsibility for the
identified hop, bound to the workflow identifier, prior chain state or prior
commitment state, presenting actor, recipient, target context, and request-
context digest.</t>
<t><tt>hop_ack</tt> MUST NOT by itself append the recipient to the actor chain.</t>
<t>A recipient MUST NOT emit <tt>hop_ack</tt> with status <tt>accepted</tt> until it has either:</t>

<ul spacing="compact">
<li>completed the requested operation; or</li>
<li>durably recorded sufficient state to recover, retry, or otherwise honor the
accepted request according to local reliability policy.</li>
</ul>
<t>A deployment MAY require <tt>hop_ack</tt> for selected hops, including terminal hops.
When <tt>hop_ack</tt> is required by policy, the calling actor and any coordinating
component MUST treat that hop as not accepted unless a valid <tt>hop_ack</tt> is
received and verified.</t>
<t><tt>hop_ack</tt> does not by itself prove successful completion or correctness of the
requested operation.</t>
<t>Recipients are not required to issue <tt>hop_ack</tt> for rejected, malformed,
abusive, unauthorized, or rate-limited requests. Absence of <tt>hop_ack</tt> is
sufficient to prevent proof of acceptance.</t>
<t>The acknowledgment payload MUST include at least:</t>

<ul spacing="compact">
<li><tt>ctx</tt> = <tt>actor-chain-hop-ack-v1</tt>;</li>
<li><tt>sid</tt>;</li>
<li><tt>achp</tt>;</li>
<li>inbound token <tt>jti</tt>;</li>
<li>presenting actor ActorID;</li>
<li>recipient ActorID;</li>
<li><tt>target_context</tt>;</li>
<li><tt>req_hash</tt>; and</li>
<li><tt>ack</tt>, whose value MUST be <tt>accepted</tt>.</li>
</ul>
<t>A <tt>hop_ack</tt> MUST be signed by the recipient using JWS or COSE, according to the
same token-format family used by the deployment. If a deployment cannot
construct a canonical request-context object for <tt>req_hash</tt>, it MUST use
<tt>hop_ack</tt> only when the inbound token is single-use for one protected request.</t>
</section>

<section anchor="threat-model"><name>Threat Model</name>
<t>This specification defines a multi-hop, multi-actor delegation model across one
or more trust domains. The security properties provided depend on the selected
profile, the correctness of sender-constrained token enforcement, the trust
relationship among participating Authorization Servers, and the availability of
step proofs or exchange records where relied upon.</t>

<section anchor="assets"><name>Assets</name>
<t>The protocol seeks to protect the following assets:</t>

<ul spacing="compact">
<li>continuity of the delegation path;</li>
<li>integrity of prior-actor ordering and membership;</li>
<li>continuity of the presenting actor;</li>
<li>binding of each hop to the intended target;</li>
<li>resistance to replay of previously accepted hop state;</li>
<li>audit evidence for later investigation and proof; and</li>
<li>minimization of prior-actor disclosure where privacy-preserving profiles are
used.</li>
</ul>
</section>

<section anchor="adversaries"><name>Adversaries</name>
<t>Relevant adversaries include:</t>

<ul spacing="compact">
<li>an external attacker that steals or replays a token;</li>
<li>a malicious actor attempting to insert, omit, reorder, or repurpose hop
state;</li>
<li>a malicious actor colluding with its home Authorization Server;</li>
<li>a malicious downstream recipient attempting to over-interpret or misuse an
inbound token;</li>
<li>an untrusted or compromised upstream Authorization Server in a multi-domain
path; and</li>
<li>an unsolicited victim service reached by a validly issued token without
having agreed to participate.</li>
</ul>
</section>

<section anchor="assumptions"><name>Assumptions</name>
<t>This specification assumes:</t>

<ul spacing="compact">
<li>verifiers can validate token signatures and issuer trust;</li>
<li>sender-constrained enforcement is correctly implemented;</li>
<li>the authenticated actor identity used in token exchange is bound to the actor
identity represented in profile-defined proofs; and</li>
<li>deployments that rely on later proof verification retain, or can discover,
the verification material needed to validate archived step proofs and exchange
records.</li>
</ul>
</section>

<section anchor="security-goals"><name>Security Goals</name>
<t>The protocol aims to provide the following properties:</t>

<ul spacing="compact">
<li>in the Asserted Delegation Path profile, silent insertion, removal,
reordering, or modification of prior actors is prevented under the assumption
that an actor does not collude with its home Authorization Server;</li>
<li>in the Selectively Disclosed Asserted Delegation Path profile, ordinary
tokens reveal only an Authorization-Server-selected ordered subset of prior
actors, and authorization is limited to that disclosed subset;</li>
<li>in the Committed Delegation Path profile, each accepted hop is additionally
bound to an actor-signed step proof and cumulative committed state, improving
detectability, provability, and non-repudiation;</li>
<li>in the Commitment-Only Delegation Path profile, ordinary tokens omit
readable prior-actor state while preserving presenting-actor continuity and
cumulative committed state for later verification; and</li>
<li>in the Selectively Disclosed Committed Delegation Path profile, ordinary
tokens reveal only an Authorization-Server-selected ordered subset of prior
actors while preserving presenting-actor continuity and cumulative committed
state for later verification.</li>
</ul>
</section>

<section anchor="non-goals"><name>Non-Goals</name>
<t>This specification does not by itself provide:</t>

<ul spacing="compact">
<li>integrity or safety guarantees for application payload content;</li>
<li>complete prevention of confused-deputy behavior;</li>
<li>concealment of prior actors from the Authorization Server that processes
token exchange;</li>
<li>branching or fan-out semantics within a single linear workflow instance; or</li>
<li>universal inline prevention of every invalid token that could be issued by a
colluding actor and its home Authorization Server.</li>
</ul>
</section>

<section anchor="residual-risks"><name>Residual Risks</name>
<t>Even when all checks succeed, a valid token chain does not imply that the
requested downstream action is authorized by local business policy. Recipients
MUST evaluate authorization using the verified presenting actor, token subject,
intended target, and local policy.</t>
<t>Deployments that depend on independently verifiable provenance for high-risk
operations SHOULD require synchronous validation of committed proof state or
otherwise treat the issuing Authorization Server as the sole trust anchor.</t>
</section>
</section>

<section anchor="security-considerations"><name>Security Considerations</name>

<section anchor="sender-constrained-enforcement-is-foundational"><name>Sender-Constrained Enforcement is Foundational</name>
<t>The security of these profiles depends strongly on sender-constrained token
enforcement. If a token can be replayed by an attacker that is not the bound
actor, continuity checks become materially weaker.</t>
</section>

<section anchor="canonicalization-errors-break-interoperability-and-proof-validity"><name>Canonicalization Errors Break Interoperability and Proof Validity</name>
<t>Any ambiguity in canonical serialization, actor identity representation, target
representation, or proof payload encoding can cause false verification failures
or inconsistent commitment values across implementations.</t>
</section>

<section anchor="readable-chain-does-not-prevent-payload-abuse"><name>Readable Chain Does Not Prevent Payload Abuse</name>
<t>A valid readable <tt>ach</tt> does not imply that the application-layer request
content is safe, correct, or policy-conformant. Recipients MUST apply local
payload validation and authorization.</t>
</section>

<section anchor="committed-profiles-depend-on-proof-retention"><name>Committed Profiles Depend on Proof Retention</name>
<t>The evidentiary benefits of the committed profiles depend on retention or
discoverability of step proofs, exchange records, and relevant verification
material. Without such retention, the profiles still provide structured
committed state, but post hoc provability and non-repudiation are materially
weakened.</t>
<t>Authorization Servers supporting committed profiles SHOULD retain proof state,
exchange records, and the historical verification material needed for later
verification for at least the maximum validity period of the longest-lived
relevant token plus a deployment-configured audit window. Retention policies
SHOULD also account for later verification during or after key rotation.</t>
</section>

<section anchor="commitment-only-delegation-path-removes-inline-prior-actor-visibility"><name>Commitment-Only Delegation Path Removes Inline Prior-Actor Visibility</name>
<t>Recipients using the Commitment-Only Delegation Path profile can validate the
presenting actor and preserved commitment continuity, but cannot authorize based
on readable prior-actor membership or order from the ordinary token alone.</t>
</section>

<section anchor="selectively-disclosed-profiles-reveal-only-a-verified-subset"><name>Selectively Disclosed Profiles Reveal Only a Verified Subset</name>
<t>Recipients using the Selectively Disclosed Asserted Delegation Path profile or
the Selectively Disclosed Committed Delegation Path profile can authorize based
only on the disclosed <tt>ach</tt> subset that they verify. They MUST treat
undisclosed prior actors as unavailable and MUST NOT infer adjacency, absence,
or exact chain length from the disclosed subset alone.</t>
<t>A malicious or compromised issuing Authorization Server can still attempt to
issue a disclosed subset that is inconsistent with the canonical full chain.
For the Selectively Disclosed Committed Delegation Path profile, committed
proof state and retained exchange records are therefore still important for
later verification and audit.</t>
</section>

<section anchor="cross-domain-re-issuance-must-preserve-chain-state"><name>Cross-Domain Re-Issuance Must Preserve Chain State</name>
<t>A cross-domain Authorization Server that re-issues a local token for the next
recipient MUST preserve the relevant chain state unchanged. Any such
re-issuance MUST continue to represent the current actor and MUST NOT append the
recipient.</t>
</section>

<section anchor="intended-recipient-checks-reduce-confused-deputy-risk"><name>Intended Recipient Checks Reduce Confused-Deputy Risk</name>
<t>Accepting Authorization Servers MUST ensure that the authenticated current actor
was an intended recipient of the inbound <tt>subject_token</tt>. This reduces a class
of deputy and repurposing attacks, though it does not eliminate all
confused-deputy scenarios.</t>
</section>

<section anchor="chain-depth"><name>Chain Depth</name>
<t>Authorization Servers SHOULD enforce a configurable maximum chain depth. A
RECOMMENDED default is 10 entries. Relying Parties MAY enforce stricter limits.</t>
</section>

<section anchor="key-management"><name>Key Management</name>
<t>Actors SHOULD use short-lived keys and/or hardware-protected keys. Deployments
that require long-term auditability MUST retain, or make durably discoverable,
the historical verification material needed to validate archived step proofs and
receiver acknowledgments after key rotation.</t>
</section>
</section>

<section anchor="privacy-considerations"><name>Privacy Considerations</name>
<t>Readable-chain profiles disclose prior actors to downstream recipients.
Deployments that do not require full readable prior-actor authorization SHOULD
consider the Commitment-Only Delegation Path profile or the Selective-
Disclosure Delegation Path profile.</t>
<t>The stable workflow identifier <tt>sid</tt> correlates all accepted hops within one
workflow instance. Accordingly, <tt>sid</tt> MUST be opaque and MUST NOT encode actor
identity, profile selection, business semantics, or target meaning.</t>
<t>Even in the privacy-preserving profiles, the Authorization Server
processing token exchange observes the authenticated current actor and any
retained chain-related state. Accordingly, these profiles reduce ordinary-token
disclosure but do not hide prior actors from the issuing Authorization Server.</t>
<t>Deployments concerned with minimization SHOULD consider:</t>

<ul spacing="compact">
<li>pairwise or pseudonymous actor identifiers;</li>
<li>omission of auxiliary claims unless receiving policy depends on them; and</li>
<li>the Selectively Disclosed Asserted Delegation Path profile or the Selectively
Disclosed Committed Delegation Path profile when partial readable-chain
disclosure is sufficient.</li>
</ul>

<section anchor="selective-disclosure"><name>Selective Disclosure</name>
<t>This specification defines the Selectively Disclosed Asserted
Delegation Path profile and the Selectively Disclosed Committed Delegation
Path profile. Both rely on a selective-disclosure encoding for <tt>ach</tt>.
JWT-based selective disclosure MUST follow SD-JWT {{!RFC9901}}. CWT-based
selective disclosure MUST follow SD-CWT {{!I-D.ietf-spice-sd-cwt}} or its
successor.</t>
<t>This specification defines the following actor-chain-specific constraints on
such use:</t>

<ul spacing="compact">
<li>the disclosed <tt>ach</tt> MUST be an ordered subsequence of the canonical
full chain for that hop;</li>
<li>the disclosed <tt>ach</tt> MUST include the current actor as its last
element;</li>
<li>if the selected profile uses step proofs or chain commitments, those
artifacts remain bound to the canonical hop progression, not to a later
disclosed subset; and</li>
<li>a verifier MUST treat undisclosed information as unavailable and MUST require
disclosure of any information needed for authorization.</li>
</ul>
</section>
</section>

<section anchor="audit-and-logging-considerations"><name>Audit and Logging Considerations</name>
<t>Authorization Servers supporting these profiles SHOULD retain records keyed by
<tt>sid</tt> and <tt>jti</tt>.</t>
<t>For committed profiles, the retention period SHOULD be at least the maximum
validity period of the longest-lived relevant token plus a deployment-
configured audit window, and it SHOULD remain sufficient to validate historical
proofs across key rotation.</t>
<t>For committed profiles, such records SHOULD include:</t>

<ul spacing="compact">
<li>prior token reference;</li>
<li>authenticated actor identity;</li>
<li>step proof reference or value;</li>
<li>issued token reference;</li>
<li>committed chain state;</li>
<li>requested audience or target context; and</li>
<li>timestamps.</li>
</ul>
<t>For selectively disclosed profiles, retained records SHOULD also allow
reconstruction of the canonical full chain asserted for the hop and the
disclosed subset issued for each recipient.</t>
<t>Actors SHOULD also retain local records sufficient to support replay detection,
incident investigation, and later proof of participation.</t>
</section>

<section anchor="appendix-a-jwt-binding-normative"><name>Appendix A. JWT Binding (Normative)</name>
<t>This appendix defines the JWT and JWS wire representation for profile-defined
ActorID values, step proofs, receiver acknowledgments, and commitment
objects.</t>

<section anchor="actorid-in-jwt"><name>ActorID in JWT</name>
<t>An ActorID is a JSON object with exactly two members:</t>

<ul spacing="compact">
<li><tt>iss</tt>: a string containing the issuer identifier; and</li>
<li><tt>sub</tt>: a string containing the subject identifier.</li>
</ul>
<t>The object MUST be serialized using JCS {{!RFC8785}} whenever it is included in
profile-defined proof or commitment inputs.</t>
<t>The <tt>ach</tt> claim, when present in a JWT, is a JSON array of ActorID
objects.</t>
</section>

<section anchor="step-proof-in-jwt"><name>Step Proof in JWT</name>
<t>The <tt>actor_chain_step_proof</tt> token request parameter value MUST be a compact JWS
string. The JWS protected header MUST contain <tt>typ=ach-step-proof+jwt</tt>. The
JWS payload MUST be the UTF-8 encoding of a JCS-serialized JSON object.</t>
<t>For the Committed Delegation Path profile, the payload MUST contain:</t>

<ul spacing="compact">
<li><tt>ctx</tt>;</li>
<li><tt>sid</tt>;</li>
<li><tt>prev</tt>;</li>
<li><tt>target_context</tt>; and</li>
<li><tt>ach</tt>.</li>
</ul>
<t>For the Commitment-Only Delegation Path profile, the payload MUST contain:</t>

<ul spacing="compact">
<li><tt>ctx</tt>;</li>
<li><tt>sid</tt>;</li>
<li><tt>prev</tt>;</li>
<li><tt>target_context</tt>; and</li>
<li><tt>actor</tt>.</li>
</ul>
<t>For the Selectively Disclosed Committed Delegation Path profile, the payload
MUST contain:</t>

<ul spacing="compact">
<li><tt>ctx</tt>;</li>
<li><tt>sid</tt>;</li>
<li><tt>prev</tt>;</li>
<li><tt>target_context</tt>; and</li>
<li><tt>ach</tt>.</li>
</ul>
<t>The <tt>prev</tt> member MUST be the base64url encoding of the prior commitment digest
or bootstrap seed bytes. The <tt>ach</tt> member MUST be a JSON array of
ActorID objects whenever that member is used. The <tt>actor</tt> member MUST be one
ActorID object whenever that member is used. The <tt>target_context</tt> member value
MUST be either a JSON string equal to <tt>aud</tt> or a JSON object that includes
<tt>aud</tt> and any additional target-selection members used by local policy. Before
any proof input is hashed or signed, <tt>target_context</tt> MUST be canonicalized
using JCS exactly once as part of the enclosing payload object; verifiers MUST
reproduce the same JCS bytes when validating the proof.</t>
<t>The JWS algorithm MUST be an asymmetric algorithm. The <tt>none</tt> algorithm MUST
NOT be used. The JWS verification key MUST be bound to the same ActorID as the
sender-constrained presentation key for the corresponding actor.</t>
</section>

<section anchor="receiver-acknowledgment-in-jwt"><name>Receiver Acknowledgment in JWT</name>
<t>A <tt>hop_ack</tt>, when used in a JWT deployment, MUST be a compact JWS string. The
JWS protected header MUST contain <tt>typ=ach-hop-ack+jwt</tt>. The JWS payload MUST
be the UTF-8 encoding of a JCS-serialized JSON object with at least these
members:</t>

<ul spacing="compact">
<li><tt>ctx</tt>;</li>
<li><tt>sid</tt>;</li>
<li><tt>achp</tt>;</li>
<li><tt>jti</tt>;</li>
<li><tt>target_context</tt>;</li>
<li><tt>req_hash</tt>;</li>
<li><tt>presenter</tt>;</li>
<li><tt>recipient</tt>; and</li>
<li><tt>ack</tt>.</li>
</ul>
<t>The <tt>presenter</tt> and <tt>recipient</tt> members MUST be ActorID objects. The <tt>ack</tt>
member MUST have the value <tt>accepted</tt>. The <tt>target_context</tt> member MUST follow
the same representation rules defined for step proofs. The <tt>req_hash</tt> member
MUST be the base64url encoding of a digest over the canonical request-context
object. The JWS signer MUST be the recipient, and the verification key MUST be
bound to the same recipient ActorID as any sender-constrained presentation key
used for the protected interaction.</t>
</section>

<section anchor="commitment-object-in-jwt"><name>Commitment Object in JWT</name>
<t>The <tt>achc</tt> claim value MUST be a compact JWS string. The JWS
protected header MUST contain <tt>typ=ach-commitment+jwt</tt>.</t>
<t>The JWS payload MUST be the UTF-8 encoding of a JCS-serialized JSON object with
exactly these members:</t>

<ul spacing="compact">
<li><tt>ctx</tt>;</li>
<li><tt>sid</tt>;</li>
<li><tt>achp</tt>;</li>
<li><tt>halg</tt>;</li>
<li><tt>prev</tt>;</li>
<li><tt>step_hash</tt>; and</li>
<li><tt>curr</tt>.</li>
</ul>
<t>The <tt>halg</tt> member MUST be either <tt>sha-256</tt> or <tt>sha-384</tt>. The members <tt>prev</tt>,
<tt>step_hash</tt>, and <tt>curr</tt> MUST be the base64url encodings of raw hash bytes.</t>
<t>The JWS payload signer MUST be the issuing Authorization Server. A verifier
MUST validate the JWS signature, verify that <tt>halg</tt> is locally permitted, then
validate that <tt>curr</tt> equals:</t>

<sourcecode type="text"><![CDATA[Hash_halg(JCS({ctx, sid, achp, halg, prev, step_hash}))
]]></sourcecode>
</section>
</section>

<section anchor="appendix-b-cwt-binding-normative"><name>Appendix B. CWT Binding (Normative)</name>
<t>This appendix defines the CWT and COSE wire representation for profile-defined
ActorID values, step proofs, receiver acknowledgments, and commitment
objects.</t>

<section anchor="actorid-in-cwt"><name>ActorID in CWT</name>
<t>An ActorID is a deterministic CBOR map with exactly two integer-labeled
members:</t>

<ul spacing="compact">
<li><tt>1</tt>: issuer identifier (<tt>iss</tt>); and</li>
<li><tt>2</tt>: subject identifier (<tt>sub</tt>).</li>
</ul>
<t>The values for labels <tt>1</tt> and <tt>2</tt> MUST be CBOR text strings.</t>
<t>The <tt>ach</tt> claim, when present in a CWT, is an array of such ActorID
maps.</t>
</section>

<section anchor="step-proof-in-cwt"><name>Step Proof in CWT</name>
<t>The <tt>actor_chain_step_proof</tt> token request parameter value MUST be the
base64url encoding of a COSE_Sign1 object {{!RFC9052}}.</t>
<t>The COSE_Sign1 payload MUST be a deterministic-CBOR-encoded map. Verifiers MUST
validate the exact <tt>ctx</tt> value and expected artifact-specific payload shape.</t>
<t>For the Committed Delegation Path profile, the payload map MUST contain:</t>

<ul spacing="compact">
<li><tt>1</tt>: <tt>ctx</tt>;</li>
<li><tt>2</tt>: <tt>sid</tt>;</li>
<li><tt>3</tt>: <tt>prev</tt>;</li>
<li><tt>4</tt>: <tt>target_context</tt>; and</li>
<li><tt>5</tt>: <tt>ach</tt>.</li>
</ul>
<t>For the Commitment-Only Delegation Path profile, the payload map MUST contain:</t>

<ul spacing="compact">
<li><tt>1</tt>: <tt>ctx</tt>;</li>
<li><tt>2</tt>: <tt>sid</tt>;</li>
<li><tt>3</tt>: <tt>prev</tt>;</li>
<li><tt>4</tt>: <tt>target_context</tt>; and</li>
<li><tt>6</tt>: <tt>actor</tt>.</li>
</ul>
<t>For the Selectively Disclosed Committed Delegation Path profile, the payload
map MUST contain:</t>

<ul spacing="compact">
<li><tt>1</tt>: <tt>ctx</tt>;</li>
<li><tt>2</tt>: <tt>sid</tt>;</li>
<li><tt>3</tt>: <tt>prev</tt>;</li>
<li><tt>4</tt>: <tt>target_context</tt>; and</li>
<li><tt>5</tt>: <tt>ach</tt>.</li>
</ul>
<t>The value of <tt>3</tt> MUST be a byte string containing the prior commitment digest or
bootstrap seed bytes. The value of <tt>5</tt> MUST be an array of ActorID maps
whenever that member is used. The value of <tt>6</tt> MUST be one ActorID map
whenever that member is used. The value of <tt>4</tt> MUST be either a CBOR text
string equal to <tt>aud</tt> or a CBOR map that includes <tt>aud</tt> and any additional
target-selection members used by local policy. Before any proof input is
hashed or signed, <tt>target_context</tt> MUST be canonicalized using deterministic
CBOR exactly once as part of the enclosing payload map; verifiers MUST
reproduce the same bytes when validating the proof.</t>
<t>The COSE algorithm MUST be asymmetric. Unprotected unauthenticated payloads MUST
NOT be used. The COSE verification key MUST be bound to the same ActorID as the
sender-constrained presentation key for the corresponding actor.</t>
</section>

<section anchor="receiver-acknowledgment-in-cwt"><name>Receiver Acknowledgment in CWT</name>
<t>A <tt>hop_ack</tt>, when used in a CWT deployment, MUST be the base64url encoding of a
COSE_Sign1 object {{!RFC9052}}. The COSE_Sign1 payload MUST be a
deterministic-CBOR-encoded map containing at least:</t>

<ul spacing="compact">
<li><tt>1</tt>: <tt>ctx</tt>;</li>
<li><tt>2</tt>: <tt>sid</tt>;</li>
<li><tt>3</tt>: <tt>achp</tt>;</li>
<li><tt>4</tt>: <tt>jti</tt>;</li>
<li><tt>5</tt>: <tt>target_context</tt>;</li>
<li><tt>6</tt>: <tt>req_hash</tt>;</li>
<li><tt>7</tt>: <tt>presenter</tt>;</li>
<li><tt>8</tt>: <tt>recipient</tt>; and</li>
<li><tt>9</tt>: <tt>ack</tt>.</li>
</ul>
<t>The values of <tt>7</tt> and <tt>8</tt> MUST be ActorID maps. The value of <tt>9</tt> MUST be the
text string <tt>accepted</tt>. The value of <tt>5</tt> MUST follow the same representation
rules defined for step proofs. The value of <tt>6</tt> MUST be a byte string
containing a digest over the canonical request-context object. The COSE signer
MUST be the recipient, and the verification key MUST be bound to the same
recipient ActorID as any sender-constrained presentation key used for the
protected interaction.</t>
</section>

<section anchor="commitment-object-in-cwt"><name>Commitment Object in CWT</name>
<t>The <tt>achc</tt> claim value MUST be a byte string containing a
COSE_Sign1 object.</t>
<t>The COSE_Sign1 payload MUST be a deterministic-CBOR-encoded map with exactly
these members:</t>

<ul spacing="compact">
<li><tt>1</tt>: <tt>ctx</tt>;</li>
<li><tt>2</tt>: <tt>sid</tt>;</li>
<li><tt>3</tt>: <tt>achp</tt>;</li>
<li><tt>4</tt>: <tt>halg</tt>;</li>
<li><tt>5</tt>: <tt>prev</tt>;</li>
<li><tt>6</tt>: <tt>step_hash</tt>; and</li>
<li><tt>7</tt>: <tt>curr</tt>.</li>
</ul>
<t>The value of <tt>4</tt> MUST be the text string <tt>sha-256</tt> or <tt>sha-384</tt>. The values of
<tt>5</tt>, <tt>6</tt>, and <tt>7</tt> MUST be byte strings containing raw hash bytes.</t>
<t>The payload signer MUST be the issuing Authorization Server. A verifier MUST
validate the COSE signature, verify that <tt>halg</tt> is locally permitted, then
validate that <tt>curr</tt> equals:</t>

<sourcecode type="text"><![CDATA[Hash_halg(Deterministic-CBOR({1:ctx, 2:sid, 3:achp, 4:halg, 5:prev, 6:step_hash}))
]]></sourcecode>
</section>
</section>

<section anchor="appendix-c-compact-end-to-end-examples-informative"><name>Appendix C. Compact End-to-End Examples (Informative)</name>

<section anchor="example-1-asserted-delegation-path-in-one-domain"><name>Example 1: Asserted Delegation Path in One Domain</name>
<t>Assume <tt>A</tt>, <tt>B</tt>, and <tt>C</tt> are governed by <tt>AS1</tt>.</t>

<ol spacing="compact">
<li><tt>A</tt> requests a token for <tt>B</tt> under the Asserted Delegation Path profile.</li>
<li><tt>AS1</tt> issues <tt>T_A</tt> with <tt>ach=[A]</tt> and <tt>aud=B</tt>.</li>
<li><tt>A</tt> calls <tt>B</tt> and presents <tt>T_A</tt>.</li>
<li><tt>B</tt> validates <tt>T_A</tt>, verifies continuity, and exchanges <tt>T_A</tt> at <tt>AS1</tt> for
a token to <tt>C</tt>.</li>
<li><tt>AS1</tt> authenticates <tt>B</tt>, verifies that <tt>B</tt> was an intended recipient of the
inbound token, appends <tt>B</tt>, and issues <tt>T_B</tt> with <tt>ach=[A,B]</tt> and
<tt>aud=C</tt>.</li>
<li><tt>B</tt> validates that the returned chain is exactly the prior chain plus <tt>B</tt>.</li>
<li><tt>B</tt> presents <tt>T_B</tt> to <tt>C</tt>.</li>
<li><tt>C</tt> validates the token and authorizes based on the readable chain <tt>[A,B]</tt>.</li>
</ol>
</section>

<section anchor="example-2-selectively-disclosed-asserted-delegation-path"><name>Example 2: Selectively Disclosed Asserted Delegation Path</name>
<t>Assume <tt>A</tt>, <tt>B</tt>, and <tt>C</tt> use the Selectively Disclosed Asserted Delegation
Path profile and accept the issuing AS as the trust anchor for disclosure
policy.</t>

<ol spacing="compact">
<li><tt>A</tt> requests a token for <tt>B</tt> under the Selectively Disclosed Asserted
Delegation Path profile.</li>
<li><tt>AS1</tt> issues <tt>T_A</tt> with a selectively disclosable <tt>ach</tt> and the
disclosure artifacts intended for <tt>B</tt>.</li>
<li><tt>A</tt> calls <tt>B</tt> and presents <tt>T_A</tt> plus the associated disclosure artifacts.</li>
<li><tt>B</tt> validates the token, verifies the selective-disclosure proof, and uses
only the disclosed chain for authorization.</li>
<li><tt>B</tt> exchanges <tt>T_A</tt> at <tt>AS1</tt> for a token to <tt>C</tt>.</li>
<li><tt>AS1</tt> reconstructs the canonical full chain for the hop, applies disclosure
policy for <tt>C</tt>, and issues <tt>T_B</tt> with a selectively disclosable
<tt>ach</tt>.</li>
<li><tt>B</tt> presents <tt>T_B</tt> and the associated disclosure artifacts to <tt>C</tt>.</li>
<li><tt>C</tt> validates the token, verifies the selective-disclosure proof, confirms
that <tt>B</tt> is the last disclosed actor, and authorizes based only on the
disclosed chain.</li>
</ol>
</section>

<section anchor="example-3-committed-delegation-path-across-two-domains"><name>Example 3: Committed Delegation Path Across Two Domains</name>
<t>Assume <tt>A</tt> and <tt>B</tt> are governed by <tt>AS1</tt>, while <tt>C</tt> is governed by <tt>AS2</tt>.</t>

<ol spacing="compact">
<li><tt>A</tt> obtains bootstrap context from <tt>AS1</tt>, signs <tt>chain_sig_A</tt>, and receives
<tt>T_A</tt> with <tt>ach=[A]</tt> and <tt>achc</tt>.</li>
<li><tt>A</tt> calls <tt>B</tt> with <tt>T_A</tt>.</li>
<li><tt>B</tt> validates <tt>T_A</tt>, constructs <tt>[A,B]</tt>, signs <tt>chain_sig_B</tt>, and exchanges
<tt>T_A</tt> at <tt>AS1</tt> for a token to <tt>C</tt>.</li>
<li><tt>AS1</tt> verifies <tt>chain_sig_B</tt>, updates the commitment, and issues <tt>T_B</tt> with
<tt>ach=[A,B]</tt> and <tt>aud=C</tt>.</li>
<li>Because <tt>C</tt> does not trust <tt>AS1</tt> directly, <tt>B</tt> performs a second exchange at
<tt>AS2</tt>.</li>
<li><tt>AS2</tt> preserves <tt>achp</tt>, <tt>sid</tt>, <tt>ach=[A,B]</tt>, and
<tt>achc</tt>, and issues a local token trusted by <tt>C</tt> that still
represents <tt>B</tt>.</li>
<li><tt>C</tt> validates the local token, sees the readable chain <tt>[A,B]</tt>, and
authorizes accordingly.</li>
</ol>
</section>

<section anchor="example-4-commitment-only-delegation-path"><name>Example 4: Commitment-Only Delegation Path</name>
<t>Assume <tt>A</tt>, <tt>B</tt>, and <tt>C</tt> use the Commitment-Only Delegation Path profile.</t>

<ol spacing="compact">
<li><tt>A</tt> obtains bootstrap context, signs <tt>chain_sig_A</tt>, and receives <tt>T_A</tt> with
<tt>achc</tt>, but no readable <tt>ach</tt>.</li>
<li><tt>A</tt> calls <tt>B</tt> with <tt>T_A</tt>.</li>
<li><tt>B</tt> validates <tt>T_A</tt>, verifies that <tt>A</tt> is the presenter, signs
<tt>chain_sig_B</tt>, and exchanges <tt>T_A</tt> at its home AS to obtain <tt>T_B</tt> for <tt>C</tt>.</li>
<li><tt>T_B</tt> contains the updated <tt>achc</tt>, but no readable chain.</li>
<li><tt>B</tt> presents <tt>T_B</tt> to <tt>C</tt>.</li>
<li><tt>C</tt> validates the token and authorizes based on the verified presenting actor
<tt>B</tt> and local policy. <tt>C</tt> MUST NOT infer prior-actor identity or count from
the commitment alone.</li>
</ol>
</section>

<section anchor="example-5-selectively-disclosed-committed-delegation-path"><name>Example 5: Selectively Disclosed Committed Delegation Path</name>
<t>Assume <tt>A</tt>, <tt>B</tt>, and <tt>C</tt> use the Selectively Disclosed Committed Delegation Path profile.</t>

<ol spacing="compact">
<li><tt>A</tt> obtains bootstrap context, signs <tt>chain_sig_A</tt>, and receives <tt>T_A</tt> with
a selectively disclosable <tt>ach</tt>, <tt>achc</tt>, and the
disclosure artifacts intended for <tt>B</tt>.</li>
<li><tt>A</tt> calls <tt>B</tt> and presents <tt>T_A</tt> plus the associated disclosure artifacts.</li>
<li><tt>B</tt> validates the token, verifies the selective-disclosure proof, and uses
only the disclosed chain for authorization.</li>
<li><tt>B</tt> signs <tt>chain_sig_B</tt> and exchanges <tt>T_A</tt> at its home AS to obtain <tt>T_B</tt>
for <tt>C</tt>.</li>
<li><tt>AS1</tt> reconstructs the canonical full chain for the hop, applies disclosure
policy for <tt>C</tt>, and issues <tt>T_B</tt> with a selectively disclosable
<tt>ach</tt> and updated <tt>achc</tt>.</li>
<li><tt>B</tt> presents <tt>T_B</tt> and the associated disclosure artifacts to <tt>C</tt>.</li>
<li><tt>C</tt> validates the token, verifies the selective-disclosure proof, confirms
that <tt>B</tt> is the last disclosed actor, and authorizes based only on the
disclosed chain.</li>
<li>If later audit is needed, the full canonical chain can be reconstructed from
retained step proofs and exchange records.</li>
</ol>
</section>
</section>

<section anchor="appendix-d-future-considerations-informative"><name>Appendix D. Future Considerations (Informative)</name>

<section anchor="terminal-recipient-handling"><name>Terminal Recipient Handling</name>
<t>This specification defines special handling for the first actor in order to
initialize chain state. It does not define corresponding terminal-hop semantics
for a final recipient that performs work locally and does not extend the chain
further.</t>
<t>Future work MAY define:</t>

<ul spacing="compact">
<li>a terminal receipt proving that the recipient accepted the request;</li>
<li>an execution attestation proving that the recipient executed a specific
operation; and</li>
<li>a result attestation binding an outcome or result digest to the final
committed state.</li>
</ul>
</section>

<section anchor="receiver-acceptance-and-unsolicited-victim-mitigation"><name>Receiver Acceptance and Unsolicited Victim Mitigation</name>
<t>This specification deliberately does not append a recipient merely because that
recipient was contacted. It also defines an OPTIONAL <tt>hop_ack</tt> extension that
lets a recipient prove accepted responsibility for a hop.</t>
<t>However, this specification still does not by itself prevent a malicious actor
from sending a validly issued token to an unsolicited victim service. Future
work MAY define stronger receiver-driven protections, including:</t>

<ul spacing="compact">
<li>stronger result attestations for completed terminal work;</li>
<li>a challenge-response model for high-risk terminal hops; and</li>
<li>recipient-issued nonces or capabilities that MUST be bound into the final
accepted hop.</li>
</ul>
</section>

<section anchor="selective-disclosure-1"><name>Selective Disclosure</name>
<t>This document now defines baseline Selectively Disclosed Asserted
Delegation Path and Selectively Disclosed Committed Delegation Path profiles.
Future work MAY define stronger selective-disclosure mechanisms, including
recipient-bound disclosure artifacts, zero-knowledge proofs over the canonical
full chain, or richer verifier-assisted consistency checks against retained
proof state.</t>
</section>

<section anchor="branching-and-fan-out"><name>Branching and Fan-Out</name>
<t>This specification models a linear workflow. A future branching profile will
need to distinguish multiple valid successors from the same prior committed
state, rather than treating every additional successor as a replay or replay-
like state collision.</t>
<t>One possible approach is to introduce explicit branch identifiers and a tree-
structured commitment model in which parallel successors become sibling nodes
under a common root. Such a profile could support inclusion proofs, partial
disclosure, and more efficient branch verification than the linear base model,
while preserving a stable workflow root.</t>
<t>Those semantics are intentionally out of scope for this base specification.</t>
</section>

<section anchor="evidence-discovery-and-governance-interoperability"><name>Evidence Discovery and Governance Interoperability</name>
<t>Committed profiles derive much of their value from later verification of step
proofs and exchange records. Future work MAY standardize interoperable evidence
discovery, retention, and verification-material publication.</t>
<t>Any such specification should define, at minimum, evidence object typing,
authorization and privacy controls for cross-domain retrieval, stable lookup
keys such as <tt>jti</tt> or <tt>sid</tt>, error handling, and retention expectations.</t>
</section>
</section>

<section anchor="appendix-e-design-rationale-and-relation-to-other-work-informative"><name>Appendix E. Design Rationale and Relation to Other Work (Informative)</name>
<t>This document complements {{!RFC8693}} by defining chain-aware token-exchange
profiles. It also aligns with the broader SPICE architecture and companion
provenance work while remaining useful on its own.</t>
<t>This specification defines five profiles instead of one deployment mode
so that implementations can choose among full readable chain-based
authorization, trust-first partial disclosure, stronger committed-state
accountability, recipient-specific committed partial disclosure, and reduced
ordinary-token disclosure without changing the core progression model.</t>
<t>The base specification remains linear. Branching, richer selective disclosure,
and evidence-discovery protocols remain future work because they require
additional identifiers, validation rules, and interoperability work.</t>
</section>

<section anchor="appendix-f-implementation-conformance-checklist-informative"><name>Appendix F. Implementation Conformance Checklist (Informative)</name>
<t>An implementation is conformant only if it correctly implements the profile it
claims to support and all common requirements on which that profile depends.</t>
<t>At a minimum, implementers should verify that they have addressed the
following:</t>
<table>
<thead>
<tr>
<th>Requirement</th>
<th>Draft section reference</th>
<th>Implemented [ ]</th>
</tr>
</thead>

<tbody>
<tr>
<td>Stable generation and preservation of <tt>sid</tt>, without relying on UUIDv4 unless local generation is augmented to satisfy the entropy requirement</td>
<td>Workflow Identifier (<tt>sid</tt>)</td>
<td>[ ]</td>
</tr>

<tr>
<td>Sender-constrained validation for every inbound token</td>
<td>Sender Constraint</td>
<td>[ ]</td>
</tr>

<tr>
<td>Exact ActorID equality over (<tt>iss</tt>, <tt>sub</tt>)</td>
<td>Actor Identity Representation</td>
<td>[ ]</td>
</tr>

<tr>
<td>Canonical serialization for all proof and commitment inputs</td>
<td>Canonicalization; Target Context Requirements; Appendix G</td>
<td>[ ]</td>
</tr>

<tr>
<td>Intended-recipient validation during token exchange</td>
<td>Intended Recipient Validation</td>
<td>[ ]</td>
</tr>

<tr>
<td>Replay and freshness handling for tokens and step proofs</td>
<td>Replay and Freshness</td>
<td>[ ]</td>
</tr>

<tr>
<td>Exact append-only checks for readable-chain profiles</td>
<td>Asserted Delegation Path Profile; Committed Delegation Path Profile</td>
<td>[ ]</td>
</tr>

<tr>
<td>Exact commitment verification for committed profiles</td>
<td>Commitment Function; Committed Delegation Path Profile</td>
<td>[ ]</td>
</tr>

<tr>
<td>Proof-key binding between ActorID, proof signer, and sender-constrained presentation key</td>
<td>Actor and Recipient Proof Keys</td>
<td>[ ]</td>
</tr>

<tr>
<td>Non-broadening Refresh-Exchange processing, if supported</td>
<td>Refresh-Exchange</td>
<td>[ ]</td>
</tr>

<tr>
<td>Policy for when <tt>hop_ack</tt> is optional or required</td>
<td>Optional Receiver Acknowledgment Extension</td>
<td>[ ]</td>
</tr>

<tr>
<td>Privacy-preserving handling of logs and error messages</td>
<td>Error Handling; Privacy Considerations</td>
<td>[ ]</td>
</tr>
</tbody>
</table></section>

<section anchor="appendix-g-canonicalization-test-vectors-informative"><name>Appendix G. Canonicalization Test Vectors (Informative)</name>
<t>The following illustrative vectors are intended to reduce interoperability
failures caused by divergent canonicalization. They are not exhaustive, but
they provide concrete byte-for-byte examples for common ActorID and
<tt>target_context</tt> inputs.</t>

<section anchor="jwt-jcs-actorid-example"><name>JWT / JCS ActorID Example</name>
<t>Input object:</t>

<sourcecode type="json"><![CDATA[{"iss":"https://as.example","sub":"svc:planner"}
]]></sourcecode>
<t>JCS serialization (UTF-8 bytes rendered as hex):</t>

<sourcecode type="text"><![CDATA[7b22697373223a2268747470733a2f2f61732e6578616d706c65222c22737562223a227376633a706c616e6e6572227d
]]></sourcecode>
<t>SHA-256 over those bytes:</t>

<sourcecode type="text"><![CDATA[7a14a23707a3a723fd6437a4a0037cc974150e2d1b63f4d64c6022196a57b69f
]]></sourcecode>
</section>

<section anchor="jwt-jcs-target-context-example"><name>JWT / JCS <tt>target_context</tt> Example</name>
<t>Input object:</t>

<sourcecode type="json"><![CDATA[{"aud":"https://api.example","method":"invoke","resource":"calendar.read"}
]]></sourcecode>
<t>JCS serialization (UTF-8 bytes rendered as hex):</t>

<sourcecode type="text"><![CDATA[7b22617564223a2268747470733a2f2f6170692e6578616d706c65222c226d6574686f64223a22696e766f6b65222c227265736f75726365223a2263616c656e6461722e72656164227d
]]></sourcecode>
<t>SHA-256 over those bytes:</t>

<sourcecode type="text"><![CDATA[911427869c76f397e096279057dd1396fe2eda1ac9e313b357d9cecc44aa811e
]]></sourcecode>
</section>

<section anchor="cwt-deterministic-cbor-actorid-example"><name>CWT / Deterministic-CBOR ActorID Example</name>
<t>Input map:</t>

<sourcecode type="text"><![CDATA[{1: "https://as.example", 2: "svc:planner"}
]]></sourcecode>
<t>Deterministic-CBOR bytes rendered as hex:</t>

<sourcecode type="text"><![CDATA[a2017268747470733a2f2f61732e6578616d706c65026b7376633a706c616e6e6572
]]></sourcecode>
<t>SHA-256 over those bytes:</t>

<sourcecode type="text"><![CDATA[67b0bc687e402cb579c2d27e45f1b6ad82e4c0ed283e4a05d62cae0fe87d59c1
]]></sourcecode>
</section>

<section anchor="cwt-deterministic-cbor-target-context-example"><name>CWT / Deterministic-CBOR <tt>target_context</tt> Example</name>
<t>Input map:</t>

<sourcecode type="text"><![CDATA[{"aud": "https://api.example", "method": "invoke", "resource": "calendar.read"}
]]></sourcecode>
<t>Deterministic-CBOR bytes rendered as hex:</t>

<sourcecode type="text"><![CDATA[a3636175647368747470733a2f2f6170692e6578616d706c65666d6574686f6466696e766f6b65687265736f757263656d63616c656e6461722e72656164
]]></sourcecode>
<t>SHA-256 over those bytes:</t>

<sourcecode type="text"><![CDATA[17b5edcf9dac7d4cec6bb0b4da8cb98ede4ebc77c7f2b1f2a1371b7a3730ec4b
]]></sourcecode>
</section>
</section>

<section anchor="appendix-h-illustrative-wire-format-example-informative"><name>Appendix H. Illustrative Wire-Format Example (Informative)</name>
<t>This appendix shows one abbreviated decoded JWT payload together with one
abbreviated decoded <tt>achc</tt> JWS payload. The values are
illustrative and signatures are omitted for readability.</t>

<section anchor="decoded-access-token-payload-example"><name>Decoded Access Token Payload Example</name>

<sourcecode type="json"><![CDATA[{
  "iss": "https://as.example",
  "sub": "svc:planner",
  "aud": "https://api.example",
  "jti": "2b2b6f0d3f0f4d7a8c4c3c4f9e9b1a10",
  "sid": "6cb5f0c14ab84718a69d96d31d95f3c4",
  "achp": "committed-delegation-path",
  "ach": [
    {"iss": "https://as.example", "sub": "svc:orchestrator"},
    {"iss": "https://as.example", "sub": "svc:planner"}
  ],
  "achc": "<compact JWS string>"
}
]]></sourcecode>
</section>

<section anchor="decoded-achc-jws-example"><name>Decoded <tt>achc</tt> JWS Example</name>
<t>Protected header:</t>

<sourcecode type="json"><![CDATA[{"alg":"ES256","typ":"ach-commitment+jwt"}
]]></sourcecode>
<t>Payload:</t>

<sourcecode type="json"><![CDATA[{
  "ctx": "actor-chain-commitment-v1",
  "sid": "6cb5f0c14ab84718a69d96d31d95f3c4",
  "achp": "committed-delegation-path",
  "halg": "sha-256",
  "prev": "SGlnaGx5SWxsdXN0cmF0aXZlUHJldkRpZ2VzdA",
  "step_hash": "z7mq8c0u9b2C0X5Q2m4Y1q3r7n6s5t4u3v2w1x0y9z8",
  "curr": "Vb8mR6b2vS5h6S8Y6j5X4r3w2q1p0n9m8l7k6j5h4g3"
}
]]></sourcecode>
<t>On the wire, the <tt>achc</tt> claim carries the usual compact-JWS
form:</t>

<sourcecode type="text"><![CDATA[BASE64URL(protected-header) "." BASE64URL(payload) "." BASE64URL(signature)
]]></sourcecode>
</section>
</section>

<section anchor="iana-considerations"><name>IANA Considerations</name>
<t>This specification does not create a new hash-algorithm registry.
<tt>achc</tt> uses hash algorithm names from the IANA Named
Information Hash Algorithm Registry {{IANA.Hash.Algorithms}}, subject to the
algorithm restrictions defined in this document.</t>

<section anchor="json-web-token-claims-registration"><name>JSON Web Token Claims Registration</name>
<t>This document requests registration of the following claims in the &quot;JSON Web
Token Claims&quot; registry established by {{!RFC7519}}:</t>
<table>
<thead>
<tr>
<th>Claim Name</th>
<th>Claim Description</th>
<th>Change Controller</th>
<th>Specification Document(s)</th>
</tr>
</thead>

<tbody>
<tr>
<td><tt>ach</tt></td>
<td>Ordered array of actor identity entries representing the delegation path.</td>
<td>IETF</td>
<td>[this document]</td>
</tr>

<tr>
<td><tt>achc</tt></td>
<td>Committed chain state binding accepted hop progression for the active profile.</td>
<td>IETF</td>
<td>[this document]</td>
</tr>

<tr>
<td><tt>achp</tt></td>
<td>Actor-chain profile identifier for the issued token.</td>
<td>IETF</td>
<td>[this document]</td>
</tr>
</tbody>
</table></section>

<section anchor="cbor-web-token-claims-registration"><name>CBOR Web Token Claims Registration</name>
<t>This document requests registration of the following claims in the &quot;CBOR Web
Token (CWT) Claims&quot; registry established by {{!RFC8392}}:</t>
<table>
<thead>
<tr>
<th>Claim Name</th>
<th>Claim Description</th>
<th>CBOR Key</th>
<th>Claim Type</th>
<th>Change Controller</th>
<th>Specification Document(s)</th>
</tr>
</thead>

<tbody>
<tr>
<td><tt>ach</tt></td>
<td>Ordered array of actor identity entries representing the delegation path.</td>
<td>TBD</td>
<td>array</td>
<td>IETF</td>
<td>[this document]</td>
</tr>

<tr>
<td><tt>achc</tt></td>
<td>Committed chain state binding accepted hop progression for the active profile.</td>
<td>TBD</td>
<td>bstr</td>
<td>IETF</td>
<td>[this document]</td>
</tr>

<tr>
<td><tt>achp</tt></td>
<td>Actor-chain profile identifier for the issued token.</td>
<td>TBD</td>
<td>tstr</td>
<td>IETF</td>
<td>[this document]</td>
</tr>
</tbody>
</table></section>

<section anchor="media-type-registration"><name>Media Type Registration</name>
<t>This document requests registration of the following media types in the
&quot;Media Types&quot; registry established by {{!RFC6838}}:</t>
<table>
<thead>
<tr>
<th>Media Type Name</th>
<th>Media Subtype Name</th>
<th>Required Parameters</th>
<th>Optional Parameters</th>
<th>Encoding Considerations</th>
<th>Security Considerations</th>
<th>Interoperability Considerations</th>
<th>Published Specification</th>
<th>Applications that use this media type</th>
<th>Fragment Identifier Considerations</th>
<th>Additional Information</th>
<th>Contact</th>
<th>Intended Usage</th>
<th>Restrictions on Usage</th>
<th>Author</th>
<th>Change Controller</th>
</tr>
</thead>

<tbody>
<tr>
<td><tt>application</tt></td>
<td><tt>ach-step-proof+jwt</tt></td>
<td>N/A</td>
<td>N/A</td>
<td>binary</td>
<td>see [this document]</td>
<td>N/A</td>
<td>[this document]</td>
<td>OAuth 2.0 Token Exchange actor-chain step proofs</td>
<td>N/A</td>
<td>Magic Number(s): N/A; File Extension(s): N/A; Macintosh File Type Code(s): N/A</td>
<td>IETF</td>
<td>COMMON</td>
<td>N/A</td>
<td>IETF</td>
<td>IETF</td>
</tr>

<tr>
<td><tt>application</tt></td>
<td><tt>ach-commitment+jwt</tt></td>
<td>N/A</td>
<td>N/A</td>
<td>binary</td>
<td>see [this document]</td>
<td>N/A</td>
<td>[this document]</td>
<td>OAuth 2.0 Token Exchange actor-chain commitments</td>
<td>N/A</td>
<td>Magic Number(s): N/A; File Extension(s): N/A; Macintosh File Type Code(s): N/A</td>
<td>IETF</td>
<td>COMMON</td>
<td>N/A</td>
<td>IETF</td>
<td>IETF</td>
</tr>

<tr>
<td><tt>application</tt></td>
<td><tt>ach-hop-ack+jwt</tt></td>
<td>N/A</td>
<td>N/A</td>
<td>binary</td>
<td>see [this document]</td>
<td>N/A</td>
<td>[this document]</td>
<td>OAuth 2.0 Token Exchange actor-chain receiver acknowledgments</td>
<td>N/A</td>
<td>Magic Number(s): N/A; File Extension(s): N/A; Macintosh File Type Code(s): N/A</td>
<td>IETF</td>
<td>COMMON</td>
<td>N/A</td>
<td>IETF</td>
<td>IETF</td>
</tr>
</tbody>
</table></section>

<section anchor="oauth-authorization-server-metadata-registration"><name>OAuth Authorization Server Metadata Registration</name>
<t>This document requests registration of the following metadata names in the
&quot;OAuth Authorization Server Metadata&quot; registry established by {{!RFC8414}}:</t>
<table>
<thead>
<tr>
<th>Metadata Name</th>
<th>Metadata Description</th>
<th>Change Controller</th>
<th>Specification Document(s)</th>
</tr>
</thead>

<tbody>
<tr>
<td><tt>actor_chain_profiles_supported</tt></td>
<td>Supported actor-chain profile identifiers.</td>
<td>IETF</td>
<td>[this document]</td>
</tr>

<tr>
<td><tt>actor_chain_commitment_hashes_supported</tt></td>
<td>Supported commitment hash algorithm identifiers.</td>
<td>IETF</td>
<td>[this document]</td>
</tr>

<tr>
<td><tt>actor_chain_receiver_ack_supported</tt></td>
<td>Indicates support for receiver acknowledgments (<tt>hop_ack</tt>) under this specification.</td>
<td>IETF</td>
<td>[this document]</td>
</tr>

<tr>
<td><tt>actor_chain_refresh_supported</tt></td>
<td>Indicates support for Refresh-Exchange under this specification.</td>
<td>IETF</td>
<td>[this document]</td>
</tr>
</tbody>
</table></section>

<section anchor="oauth-parameter-registration"><name>OAuth Parameter Registration</name>
<t>This document requests registration of the following parameter names in the
relevant OAuth parameter registry:</t>
<table>
<thead>
<tr>
<th>Parameter Name</th>
<th>Parameter Usage Location</th>
<th>Change Controller</th>
<th>Specification Document(s)</th>
</tr>
</thead>

<tbody>
<tr>
<td><tt>actor_chain_profile</tt></td>
<td>OAuth token endpoint request</td>
<td>IETF</td>
<td>[this document]</td>
</tr>

<tr>
<td><tt>actor_chain_step_proof</tt></td>
<td>OAuth token endpoint request</td>
<td>IETF</td>
<td>[this document]</td>
</tr>

<tr>
<td><tt>actor_chain_refresh</tt></td>
<td>OAuth token endpoint request</td>
<td>IETF</td>
<td>[this document]</td>
</tr>
</tbody>
</table></section>
</section>

</middle>

<back>

</back>

</rfc>
