WIMSE R. Asor Internet-Draft Attenu Intended status: Standards Track 15 October 2026 Expires: 18 April 2027 Verifiable Attenuated Delegation for AI Agent Chains draft-asor-wimse-agent-delegation-chain-02 Abstract AI agents increasingly delegate tasks to other agents. Each delegation should convey only a subset of the delegating party's authority, that subset should be bounded in scope, magnitude, and time, and any enforcement point should be able to verify -- offline, with no call to an authorization server -- that a token presented at hop N carries authority no greater than the token at hop N-1, back to a trusted root, and that every hop acts under the same accountable principal. OAuth 2.0 Token Exchange (RFC 8693) models two-party delegation and records prior actors in a nested "act" claim, but that claim is informational only and cannot enforce attenuation across a chain of depth two or more. This document defines the Agent Delegation Chain: a profile of OAuth 2.0 JWT access tokens (RFC 9068) that carries authority as Rich Authorization Requests (RFC 9396), binds the chain to one principal and names the agent acting at each hop, links each delegation to its parent by a cryptographic byte- commitment, and specifies a deterministic offline verification algorithm that enforces monotonic attenuation, bounded depth, monotonic expiry, and principal invariance. It reuses existing JOSE, proof-of-possession (RFC 9449), and status-list machinery (the OAuth Status List draft) and introduces no new cryptography. Status of This Memo This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet- Drafts is at https://datatracker.ietf.org/drafts/current/. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress." This Internet-Draft will expire on 18 April 2027. Asor Expires 18 April 2027 [Page 1] Internet-Draft Agent Delegation Chain October 2026 Copyright Notice Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved. This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/ license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License. Table of Contents 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 1.1. The gap in existing mechanisms . . . . . . . . . . . . . 3 2. Conventions and Definitions . . . . . . . . . . . . . . . . . 4 3. Token Format . . . . . . . . . . . . . . . . . . . . . . . . 5 3.1. Principal and Acting Agent . . . . . . . . . . . . . . . 6 4. Authority Representation . . . . . . . . . . . . . . . . . . 7 4.1. Scope Syntax and Wildcards . . . . . . . . . . . . . . . 7 4.2. Constraint Vocabulary . . . . . . . . . . . . . . . . . . 9 4.3. Subsumption Rules . . . . . . . . . . . . . . . . . . . . 10 4.4. Authorization Detail Types and the Verifier . . . . . . . 11 4.5. Open Issue: Scope Vocabulary . . . . . . . . . . . . . . 12 5. Chain Linkage . . . . . . . . . . . . . . . . . . . . . . . . 13 6. Offline Verification Algorithm . . . . . . . . . . . . . . . 13 6.1. What Verification Establishes . . . . . . . . . . . . . . 15 6.2. Verification Outcomes . . . . . . . . . . . . . . . . . . 16 6.3. Several Chains Reaching One Agent . . . . . . . . . . . . 18 6.4. Open Issue: Trust-Anchor Provenance . . . . . . . . . . . 19 7. Holder Binding . . . . . . . . . . . . . . . . . . . . . . . 19 8. Revocation . . . . . . . . . . . . . . . . . . . . . . . . . 19 9. Security Considerations . . . . . . . . . . . . . . . . . . . 20 9.1. Parent tokens remain valid after attenuation . . . . . . 20 9.2. Chain splicing . . . . . . . . . . . . . . . . . . . . . 20 9.3. Confused deputy and over-broad delegation . . . . . . . . 20 9.4. Unbounded depth, fan-out, and aggregate budgets . . . . . 21 9.5. Offline verification vs. revocation latency . . . . . . . 22 9.6. Why not macaroons; algorithm agility . . . . . . . . . . 23 9.7. Root issuance is the policy decision point . . . . . . . 23 10. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 23 11. Implementation Status . . . . . . . . . . . . . . . . . . . . 24 12. References . . . . . . . . . . . . . . . . . . . . . . . . . 25 12.1. Normative References . . . . . . . . . . . . . . . . . . 25 12.2. Informative References . . . . . . . . . . . . . . . . . 27 Asor Expires 18 April 2027 [Page 2] Internet-Draft Agent Delegation Chain October 2026 Appendix A. Acknowledgments . . . . . . . . . . . . . . . . . . 29 Appendix B. Reference Implementation and Test Vectors . . . . . 30 Appendix C. Changes Since -01 . . . . . . . . . . . . . . . . . 31 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 33 1. Introduction An AI agent that receives a task from a user or another agent frequently decomposes it and delegates sub-tasks to further agents or tools. In production deployments this produces delegation chains of depth greater than two. The security requirement is a single invariant: the authority exercised at any hop MUST be a subset of the authority granted at the hop that delegated to it, and this MUST be verifiable by the enforcement point that ultimately honors a tool call, without that point contacting an authorization server. 1.1. The gap in existing mechanisms OAuth 2.0 Token Exchange [RFC8693] defines delegation and impersonation semantics and a nestable "act" claim. However, [RFC8693] Section 4.1 states that a recipient considers only the top- level claims and the current (outermost) actor; the nested chain is history for audit, not enforced authority. Token Exchange also normally contacts the authorization server at each hop. Neither property supports offline, enforced, depth >= 2 attenuation. Cross-domain identity chaining (see [I-D.ietf-oauth-identity-chaining]) and transaction tokens address related but distinct problems (crossing trust domains and propagating immutable context within one domain, respectively) and explicitly do not provide chained cryptographic attenuation. Capability systems that do provide offline attenuation -- macaroons [Macaroons], Biscuit [Biscuit] -- either verify with a shared secret (macaroons: symmetric HMAC, so every verifier holds the minting key) or use a non-IETF wire format (Biscuit: protocol buffers with an embedded Datalog engine). The historical standards-track ancestor is SDSI/SPKI [RFC2693]. This document fills the gap by reusing the JOSE/OAuth stack and adding only the chain linkage, the principal binding, and the subsumption-enforcing verification algorithm. It is designed as the attenuation mechanism satisfying requirements R1 and R5 of [I-D.reece-wimse-cross-org-delegation] and as a companion to [I-D.ietf-wimse-aims], whose placement of the acting agent in "client_id" and the on-behalf-of party in "sub" this profile follows. It shares its approach with, and is intended to converge with, [I-D.niyikiza-oauth-attenuating-agent-tokens] and Asor Expires 18 April 2027 [Page 3] Internet-Draft Agent Delegation Chain October 2026 [I-D.coetzee-oauth-spt-txn-tokens]. Its offline verification model is complementary to the online Delegation Server and synchronous revocation model in [I-D.sweeney-wimse-credential-delegation]. The two are halves of one design, separated by a single axis: whether a server is in the path. The in-token mechanisms this document requires -- constraints carried in the token, parent-hash verification, and a child expiry bounded by its parent's -- are how a verifier with no network reconstructs what such a server would otherwise know first-hand; where a server is in every hop, they are redundant rather than absent. The verifier-side evaluation rules of [I-D.jackson-wimse-evaluation] describe the receiving half of the same problem; this document cites that work informatively, and no requirement here depends on it. 2. Conventions and Definitions The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. Delegation Token (DT): An OAuth 2.0 JWT access token [RFC9068] profiled by this document, carrying the authority granted to one agent at one hop of a chain. Delegation Chain: An ordered sequence of Delegation Tokens DT_0, DT_1, ... DT_n, where DT_0 is the root, and each DT_i (i > 0) is linked to DT_{i-1} by the mechanism in Section 5. A chain is one path. An agent that holds tokens issued along several paths holds several chains; see Section 6.3. Principal: The party accountable for the chain: the party whose grant every token in the chain acts under. Carried in "sub", identical at every hop (Section 3). Acting Agent: The agent that holds, and acts under, one Delegation Token. Carried in "client_id", which names the agent acting at each hop. Authority: The set of permitted scope values carried by an "agent_delegation" authorization detail in the "authorization_details" claim [RFC9396], together with the constraints in Section 4.2. Attenuation: The construction of a child Delegation Token whose Authority is a subset of its parent's, per the subsumption rules in Section 4.3. Asor Expires 18 April 2027 [Page 4] Internet-Draft Agent Delegation Chain October 2026 Enforcement Point: The component that verifies a Delegation Chain and permits or denies an action. Verifier: Any component that runs the algorithm of Section 6, whether or not it is presented with an action. An Enforcement Point is a Verifier that is presented with an action and decides it. 3. Token Format A Delegation Token is a JWT [RFC7519] signed with JWS [RFC7515] using a fully-specified algorithm [RFC9864]. Implementations MUST support Ed25519 [RFC8032] [RFC8037] and MAY support ES256 and, for post- quantum readiness, ML-DSA [RFC9964]. The token uses the "application/at+jwt" header type of [RFC9068] and includes the claims that profile requires: "iss", "exp", "aud", "sub", "client_id", "iat", and "jti". The protected header SHOULD contain "c14n": "JCS" as an informational label. Verifiers MUST NOT rely on this field. The canonicalization of the protected header and payload JSON is the JSON Canonicalization Scheme (JCS) [RFC8785]: producers MUST serialize both with JCS before base64url encoding, and verifiers MUST reject either decoded byte string unless it is exactly the JCS serialization of the parsed object. Verifiers MUST also reject duplicate object member names, non-finite numbers, and lone UTF-16 surrogates. Because JCS numbers are IEEE 754 binary64 values, an integer whose magnitude exceeds 2^53-1 is not represented exactly; producers MUST NOT emit one, and verifiers MUST reject a token carrying one as malformed. The [RFC9068] claims carry the following meaning in a Delegation Token: sub: REQUIRED. The Principal. [RFC9068] Section 2.2 makes "sub" the resource owner where one exists; in a Delegation Chain the resource owner is the party whose grant the chain acts under, and the same value MUST appear in every DT_i of the chain. A verifier denies a chain in which any DT_i carries a "sub" that differs from DT_0's (Section 6, step 3). A chain whose DT_0 carries no "sub", or a "sub" that is not a non-empty string, is malformed. client_id: REQUIRED. The Acting Agent at this hop, as a string. It identifies which software exercised the authority; "sub" identifies whose grant it exercised. The value MAY be a workload identifier as defined by [I-D.ietf-wimse-identifier]; this document places no requirement on its format beyond being a string. aud: REQUIRED. The audience, as [RFC7519] Section 4.1.3 defines it: Asor Expires 18 April 2027 [Page 5] Internet-Draft Agent Delegation Chain October 2026 a string, or an array of one or more strings. A token whose "aud" is absent, null, or an empty array is malformed. The Enforcement Point applies the audience check of [RFC9068] Section 4 to DT_n (Section 6, step 8); this document places no requirement on the audience of DT_i for i < n beyond presence and shape. iss, exp, iat, jti: REQUIRED, as in [RFC9068]. "exp" is additionally subject to the monotonic expiry rule of Section 4.3. "jti" identifies the token instance for the purposes of Section 5 and of per-lifetime constraints (Section 4.2). In addition, a Delegation Token contains: authorization_details: REQUIRED. An array of authorization detail objects [RFC9396] expressing the Authority. See Section 4. cnf: REQUIRED. A confirmation claim [RFC7800] binding the token to the holder's key, proven per DPoP [RFC9449]. See Section 7. del_depth: REQUIRED. A non-negative integer; the position of this token in the chain. DT_0 has del_depth 0. del_max_depth: REQUIRED in DT_0. A positive integer; the maximum permitted chain length. MUST NOT be increased by any child (see Section 4.3). par_hash: REQUIRED in every DT_i with i > 0; MUST be absent in DT_0. The base64url-encoded SHA-256 digest of the parent token's JWS Signing Input ([RFC7515] Section 5.1), i.e. of the exact bytes "ASCII(BASE64URL(parent JOSE Header)) || '.' || ASCII(BASE64URL(parent JWS Payload))". This is the byte- commitment that binds a child to one specific parent and prevents chain splicing. 3.1. Principal and Acting Agent A Delegation Chain answers two questions that a holder key alone does not: who is accountable for what the chain does, and which agents took part. The first is answered by "sub", which names the Principal and is invariant along the chain: a child token is issued under the same grant as its parent, so it names the same Principal, and a token that names a different one is not a member of the chain. The second is answered by "client_id", which names the agent acting at each hop. Together they make a chain auditable as well as verifiable. The "par_hash" commitment (Section 5) already prevents a child from being re-parented onto a different token. It does not, by itself, prevent a child from carrying a different "sub" than its parent, Asor Expires 18 April 2027 [Page 6] Internet-Draft Agent Delegation Chain October 2026 because the child is a new token with its own payload. The invariance check in step 3 of Section 6 is what closes that gap, and it is a comparison of two strings, not new machinery. This revision defines no transition mode for chains shaped by the previous revision. A chain whose tokens carry no "client_id" or no "cnf", or whose "aud" is null, is malformed under this revision. A verifier that also accepts such chains under the previous revision's rules does so outside this document and reports which revision's rules it applied. 4. Authority Representation For this profile, Authority is expressed by an authorization detail object [RFC9396] whose "type" is "agent_delegation". A Delegation Token MUST carry exactly one authorization detail object, and its type MUST be "agent_delegation"; a token carrying a second detail, or a detail of any other type, is malformed (Section 4.4). The object contains a REQUIRED "scopes" member: an array of strings, where each string names one permitted operation. An empty array conveys no permitted operation. Numeric and enumerated bounds ("ceilings") that [RFC9396] does not standardize are carried in the "constraints" member defined here. The object MUST NOT carry members other than "type", "scopes", and "constraints"; a verifier that encounters another member MUST reject the token as malformed, because it would otherwise report success on a detail it had not fully read. 4.1. Scope Syntax and Wildcards Each member of "scopes" MUST match the following ABNF [RFC5234]: lower = %x61-7A digit = %x30-39 segment = lower *(lower / digit / "_" / "-") literal-scope = segment "." segment *("." segment) wildcard-scope = segment *("." segment) ".*" opaque-scope = 1*( %x21 / %x23-29 / %x2B-5B / %x5D-7E ) scope = literal-scope / wildcard-scope / opaque-scope The "opaque-scope" form is the "scope-token" of [RFC6749] Section 3.3 with the asterisk (%x2A) removed. It exists so that a chain can carry a scope string issued by an OAuth authorization server under that server's own naming, which the two structured forms do not admit. A verifier classifies each scope value by its bytes alone, trying the forms in this order: a value that matches "literal-scope" is a literal scope; otherwise, a value that matches "wildcard-scope" is a Asor Expires 18 April 2027 [Page 7] Internet-Draft Agent Delegation Chain October 2026 wildcard scope; otherwise, a value that matches "opaque-scope" is an opaque scope. A value that matches none of the three, for example one that contains an asterisk anywhere other than as a complete final segment following a dot, is invalid. Thus crm.read is a literal scope, crm.* is a wildcard scope, User.Read and openid are opaque scopes, and the bare value *, the partial-segment form crm.re*, and the non-terminal form crm.*.read are invalid. A producer MUST NOT emit an invalid scope. A verifier that encounters one MUST reject the Delegation Token as malformed before evaluating subsumption. There is no case folding: User.Read and user.read are two different scopes. The covering relation between a parent scope and a child scope is: * A parent literal scope covers only an identical child scope. * A parent wildcard scope covers any child scope, literal or wildcard, whose value begins with the parent value after removing only the final * and retaining the dot. Therefore crm.* covers "crm.read", "crm.x.y.z", and crm.x.*; it does not cover the bare name "crm" or the adjacent namespace "crmx.read". Wildcard coverage is segment-bounded and extends to any depth below the named prefix, and a wildcard covers a narrower wildcard under its prefix. * A parent opaque scope covers only a byte-identical child scope. No wildcard scope covers an opaque scope, and an opaque scope covers no wildcard scope. One consequence of classifying by bytes alone is stated here so that deployments can plan for it: a scope string issued by an authorization server that happens to match "literal-scope" is treated as a literal scope, and a wildcard over its prefix covers it. A deployment that needs such a scope to match exactly should not grant a wildcard over its prefix; doing so also gives up wildcard coverage for every other scope under that prefix. This document provides no registry by which a verifier could tell a dotted provider string from a structured literal, and does not add one. This covering relation belongs to the "agent_delegation" authorization detail type; see Section 4.4 for how the relation is bound to the type. Asor Expires 18 April 2027 [Page 8] Internet-Draft Agent Delegation Chain October 2026 4.2. Constraint Vocabulary The "constraints" member is an array of objects. Each object contains a REQUIRED "key" member, a string identifying the constrained dimension, and exactly one typed constraint value, whose member name is the constraint type. A constraint object is closed: its members are "key", that one type member, and any member the type's definition adds ("order" for "rank"). A constraint object carrying any other member is malformed, and a verifier MUST reject the token. This document defines: * "max" : a number. The value of the associated quantity in one authorized action MUST NOT exceed it (e.g. {"key": "max_rows", "max": 5000}). It is measured per action: nothing in this type aggregates across actions, tokens, siblings, or a subtree. * "max_lifetime" : a number. The sum of the associated quantity over every action authorized under the token carrying it, identified by "jti", MUST NOT exceed it (e.g. {"key": "max_calls", "max_lifetime": 50}). It is measured per token lifetime. A re- issued token (Section 5) is a new "jti" and starts a new total; an issuer that needs a bound to span re-issuance issues the new token with the bound reduced by the amount already consumed. * "max_subtree" : a number. The sum of the associated quantity over every action authorized under the token carrying it and under every token descended from it MUST NOT exceed it. It is measured per subtree. Enforcing it requires accounting across tokens; see Section 9.4 for what an offline verifier can and cannot do with it. * "min" : a number. The value of the associated quantity in one authorized action MUST NOT be less than it (e.g. {"key": "tenure_years", "min": 2}). Where "max" carries a ceiling tightened downward, "min" carries a floor tightened upward. * "one_of" : an array. The associated value MUST be a member. * "not_one_of" : an array. The associated value MUST NOT be a member. * "prefix" : a string. The associated value MUST have it as a prefix. * "rank" : a string naming a position in an ordered enumeration. The constraint object additionally carries an "order" member: an array of two or more distinct strings listing the enumeration from least to most permissive, of which "rank" MUST be one (e.g. Asor Expires 18 April 2027 [Page 9] Internet-Draft Agent Delegation Chain October 2026 {"key": "egress", "rank": "internal", "order": ["none", "internal", "any"]}). The associated value MUST be a member of "order" whose position does not exceed that of "rank". The ordering travels with the constraint so that a verifier needs no registry entry per key; a constraint of type "rank" that lacks "order", or whose "rank" is not a member of "order", is malformed. The three measurement scopes -- per action, per token lifetime, per subtree -- are distinct constraint types because they are enforced by different machinery: a per-action bound is decided from the request alone, a per-lifetime bound needs a running total held by the component that authorizes actions under that token, and a per-subtree bound needs a total that spans tokens. A producer MUST NOT emit a cumulative bound under the "max" type. A per-action "max" on a quantity that exists only as a running count, such as a count of calls, bounds nothing, since each action contributes one; a producer bounds a count with "max_lifetime" or "max_subtree". A verifier that holds only the chain checks that a child's per-lifetime and per- subtree bounds are no wider than its parent's (Section 4.3); whether the spend is under the bound is checked only where the running total is held, and an enforcement point that has no access to that total denies (Section 6, step 8). The running total is supplied by the component that holds it, through a channel separate from the request's own parameters; a value the request asserts about its own total is not a total. Within one authorization detail object, the pair (key, type) identifies a constraint. A detail MUST NOT carry two constraints with the same key and the same type, and a verifier MUST reject a token that does as malformed, rather than choosing one of them. Two constraints with the same key and different types (for example a "min" and a "max" on one quantity, forming a range) are permitted and are evaluated independently. The registry in Section 10 allows new constraint types. A verifier that encounters an unknown constraint type MUST treat the action as denied (fail-closed), never as unconstrained. 4.3. Subsumption Rules An Authority C is subsumed by an Authority P (written C <= P) if and only if all of the following hold: 1. Every scope in C's "agent_delegation" detail is covered by at least one scope in P's "agent_delegation" detail according to Section 4.1, and Asor Expires 18 April 2027 [Page 10] Internet-Draft Agent Delegation Chain October 2026 2. for every constraint (key, type) present in P, a constraint with the same key and the same type is present in C whose admissible set is a subset of P's: for "max", "max_lifetime", and "max_subtree", C.value <= P.value; for "min", C.value >= P.value; for "one_of", C's array is a subset of P's; for "not_one_of", C's array is a superset of P's; for "prefix", C's string begins with P's; for "rank", C's "order" is identical to P's, element for element, and the position of C's "rank" in it does not exceed the position of P's, and 3. a constraint (key, type) present in P MUST NOT be absent in C (absence means unbounded, which is not a subset), and 4. C.exp <= P.exp (monotonic expiry), and 5. C.del_max_depth <= P.del_max_depth. No inference is made across constraint types: a "max_lifetime" in C does not satisfy a "max" in P, and a "max" in C does not satisfy a "max_lifetime" in P, whatever their values. A verifier that does not implement the type of a constraint present in P cannot evaluate rule 2 for it; it MUST treat the chain as not subsumed unless C carries a constraint with the same key and type whose JCS serialization [RFC8785] is byte-identical to P's, and even then the action is denied at step 8 of Section 6 under the fail-closed rule of Section 4.2. Attenuation is the construction of C as the greatest lower bound (meet) of P and a request R under these rules. Because the meet can only narrow, C <= P holds by construction for every R. 4.4. Authorization Detail Types and the Verifier [RFC9396] does not maintain a registry of authorization detail type values; its Section 2.1 recommends that an API designer use a collision-resistant namespace under the designer's control, such as a URI. The type value "agent_delegation" is the one this document and its test vectors use; whether a later revision moves it to a URI-form value under such a namespace is an open question, and the wire value is unchanged by this revision. The covering relation a verifier applies at step 4 of Section 6 is specified per authorization detail type. For "agent_delegation" it is the relation in Section 4.1 together with the constraint rules of Section 4.3. Another authorization detail type, if defined, specifies its own relation, and that relation is what a verifier applies to details of that type. The type selects the relation. Asor Expires 18 April 2027 [Page 11] Internet-Draft Agent Delegation Chain October 2026 A verifier MUST evaluate every authorization detail object in every DT_i, or reject the token. A detail whose type the verifier does not implement is one it cannot evaluate, and the token MUST be rejected as malformed; a verifier that skips a detail it does not understand has reported success on a token it did not read. The verifier classifies detail types when it parses a token, before step 1 of Section 6, so that DT_0 is subject to the rule as every other token is. Under this revision the only type a token may carry is "agent_delegation", and it may carry exactly one detail (Section 4); a later revision may define chains whose tokens carry details of several types, and the per-type binding of the covering relation stated above is what such a definition would build on. A resource server SHOULD declare the types it implements in the "authorization_details_types_supported" member of its protected resource metadata ([RFC9728], Section 2), so that an issuer can learn which chains it will accept. [I-D.jackson-wimse-evaluation] states the same process-every-entry-or-refuse rule from the verifier's side; the requirement here stands on its own. Which chains a verifier accepts across deployments is a trust decision the verifier already makes by the root keys it holds (Section 6, step 1); two verifiers that both implement "agent_delegation" apply the same covering relation to the same chain. 4.5. Open Issue: Scope Vocabulary Subsumption is syntactic. Two deployments that both implement "agent_delegation", and attach different meanings to the same scope verbs, both verify the same chain clean and read it differently, because nothing in the token says what "crm.read" permits. A profile or registry of common operation verbs would close that gap. This document states the limit and supplies neither. A companion document that does supply one is expected to take the result of the native verification in Section 6 as an input rather than re-implement it; to map a scope family to an action definition explicitly; and, where a mapping is ambiguous, to refuse rather than resolve. A companion document is cited from this one when it is an Internet-Draft, so that every reader can cite it by a stable name. Asor Expires 18 April 2027 [Page 12] Internet-Draft Agent Delegation Chain October 2026 5. Chain Linkage Each child token commits to its parent by "par_hash" (Section 3). This binds the child to the parent's exact serialized bytes, so a child cannot be re-parented onto a different (e.g. broader) token: doing so changes the parent's Signing Input and thus its SHA-256 digest, which no longer matches the child's "par_hash". The digest is over the already-serialized JWS Signing Input; the protected header and payload that form that input are JCS [RFC8785] as required by Section 3. The commitment is to a parent token instance, not to a parent identity. A child's chain carries the parent instance the child commits to. When a parent is re-issued -- for example refreshed before expiry with a new "jti", "iat", and "exp" -- the re-issued token is a different token, outside the chain of any child issued under the previous instance. Re-issuing a parent therefore does not invalidate its existing children: they continue to verify with the instance they were issued under until that instance expires or a token in their chain is revoked (Section 8), and a child presented together with a re-issued parent instead of the instance it commits to is denied at step 2 of Section 6. The operational consequence for the refresh rate is in Section 9.5. A parent identity that survives re-issuance is not defined by this document. 6. Offline Verification Algorithm An Enforcement Point presented with a Delegation Chain DT_0 ... DT_n and an attempted action A, and holding the trusted root public key(s), MUST perform the following, denying on the first failure: 1. Verify the JWS signature of every DT_i using a fully-specified algorithm [RFC9864]. The verifier MUST hold a local list of accepted algorithms, and MUST deny the chain if the "alg" of any DT_i is not on that list, even where the signature verifies. The verifier MUST take the algorithm from its own configuration for the key, and MUST deny if the "alg" header names a different one. DT_0 MUST verify under a trusted root key. 2. For each i > 0, compute SHA-256 of DT_{i-1}'s JWS Signing Input and compare, in constant time, to DT_i's "par_hash". Any mismatch: deny. 3. Check chain shape, depth first. Depth: DT_0.del_depth == 0; DT_i.del_depth == i; n < DT_0.del_max_depth. Then principal: DT_0.sub is a non-empty string, and for every i, DT_i.sub is identical to DT_0.sub. Otherwise deny. Asor Expires 18 April 2027 [Page 13] Internet-Draft Agent Delegation Chain October 2026 4. For each i > 0, verify DT_i.Authority <= DT_{i-1}.Authority under rules 1, 2, 3, and 5 of Section 4.3. A token carrying a second detail, or a detail of a type other than "agent_delegation", was rejected as malformed when it was parsed (Section 4.4). Any violation: deny. 5. Check time: for every i, nbf (if present) <= now <= exp, and exp is monotonic non-increasing along the chain (rule 4 of Section 4.3). Otherwise deny. 6. Verify holder binding: the presenter proves possession of the key in DT_n.cnf via a valid DPoP proof [RFC9449] bound to this request. Otherwise deny. 7. Check revocation: consult the Token Status List [I-D.ietf-oauth-status-list] reference in each DT_i (if present) against a cached list. A cached status answer is trusted for its time to live, so the window in which a revoked token is still honored is that time to live and no longer. A status reference that is present but whose list cannot be fetched, or whose cached answer has outlived its time to live and cannot be refreshed, is UNKNOWN, and the verifier MUST deny: unknown is not not-revoked. If any DT_i is revoked, deny (and, by local policy, treat the whole subtree as revoked). A token issued with no status reference is a choice made at issuance (Section 8) and is not denied on that account. 8. Authorize A against DT_n: confirm that the Enforcement Point is identified by DT_n's "aud" as [RFC9068] Section 4 requires; then check A against DT_n.Authority: its scope, every per-action constraint ("max", "min", "one_of", "not_one_of", "prefix", "rank"), and every cumulative constraint ("max_lifetime", "max_subtree"). A cumulative constraint is checked where the running total it is measured over is held: by the Enforcement Point itself, or by a component that holds that total and authorizes A on the Enforcement Point's behalf (Section 9.4). The total reaches the check through a channel separate from the request's own parameters, never from the request: a cumulative constraint is evaluated against that total only, and a per-action constraint against the request only, so a name the two share cannot let one stand in for the other. An Enforcement Point that neither holds the running total for a cumulative constraint DT_n carries nor has A authorized by a component that does MUST deny. Permit only if A is within DT_n.Authority on every count. The algorithm is deterministic, side-effect free, and requires no network call except the (cacheable, offline-checkable) status list of step 7. The one exception is the cumulative-constraint check of step Asor Expires 18 April 2027 [Page 14] Internet-Draft Agent Delegation Chain October 2026 8, which belongs to the component holding the running total and lies outside that guarantee. The order of steps 1 to 5 is the order in which a chain presented without an action can be checked (Section 6.1); steps 6 and 8 need the request, and step 7 needs the status list. 6.1. What Verification Establishes A Verifier is not always an Enforcement Point. An auditor re- checking a recorded chain, an issuer validating a parent before minting a child, or a component that holds a chain but no request, can run steps 1 to 5 and, if a status list is available, step 7. Table 1 states what such a Verifier may and may not conclude. +========================+=============+========================+ | Property | Chain alone | With the request | | | (steps 1-5, | (steps 6, 8) | | | 7) | | +========================+=============+========================+ | Every token is well- | yes | yes | | formed, JCS-canonical, | | | | and signed under an | | | | accepted algorithm | | | +------------------------+-------------+------------------------+ | DT_0 is signed under a | yes | yes | | trusted root key | | | +------------------------+-------------+------------------------+ | Each child commits to | yes | yes | | the parent instance | | | | presented with it | | | +------------------------+-------------+------------------------+ | Depth is bounded and | yes | yes | | the Principal is | | | | unchanged along the | | | | chain | | | +------------------------+-------------+------------------------+ | Each hop's Authority | yes | yes | | is a subset of its | | | | parent's | | | +------------------------+-------------+------------------------+ | Every token is within | yes | yes | | its validity window at | | | | the instant checked | | | +------------------------+-------------+------------------------+ | No token in the chain | yes, if the | yes, if the list is | | is revoked, within the | list is | reachable | | status list's time to | reachable | | | live | | | Asor Expires 18 April 2027 [Page 15] Internet-Draft Agent Delegation Chain October 2026 +------------------------+-------------+------------------------+ | The presenter holds | no | yes | | the key DT_n is bound | | | | to | | | +------------------------+-------------+------------------------+ | A specific action is | no | yes | | permitted | | | +------------------------+-------------+------------------------+ | A per-lifetime total | no | only where the total | | is within bound | | is held; otherwise | | | | step 8 denies | +------------------------+-------------+------------------------+ | A per-subtree total is | no | only where the total | | within bound | | is held (Section 9.4); | | | | otherwise step 8 | | | | denies | +------------------------+-------------+------------------------+ Table 1: What a Verifier may conclude, by the steps it performed The "subset" row holds for the constraint types the Verifier implements. A constraint type it does not implement fails closed under the rule in Section 4.3, so it can turn a "yes" into a "no" and never the reverse. A Verifier that has not performed step 6 has established that the chain is valid, not that the party presenting it is its holder, and MUST NOT report the chain as authorizing anything. A Verifier that has not performed step 8 has established the leaf Authority as a set and MUST NOT report any action as permitted. Such a Verifier SHOULD report its result as the chain's validity together with the steps it did not perform. 6.2. Verification Outcomes Independent implementations are compared by their outcomes on shared test vectors (Appendix B), and the comparison is only as good as the agreement on how a denial is named. A verifier SHOULD report a denial under the name that Table 2 gives for the check that failed, which is the vocabulary the test vectors declare; since the algorithm denies on the first failure, one denial carries one name. A verifier MAY add detail of its own beside the name. The names are not carried in any token and have no effect on the wire. Asor Expires 18 April 2027 [Page 16] Internet-Draft Agent Delegation Chain October 2026 +=======================+=======+================================+ | Name | Step | Meaning | +=======================+=======+================================+ | malformed | parse | a token is not three base64url | | | | parts, a claim this document | | | | requires is absent or of the | | | | wrong shape, an integer's | | | | magnitude exceeds 2^53-1, a | | | | scope is invalid, a constraint | | | | is malformed or repeated, a | | | | detail carries an unknown | | | | member, a token carries more | | | | than one detail, or a detail | | | | type is not "agent_delegation" | +-----------------------+-------+--------------------------------+ | non_canonical | parse | a decoded header or payload is | | | | not the JCS serialization of | | | | what it parses to | +-----------------------+-------+--------------------------------+ | duplicate_member | parse | a JSON object repeats a member | | | | name | +-----------------------+-------+--------------------------------+ | non_finite | parse | a number is NaN or an | | | | infinity, which JSON and JCS | | | | do not represent | +-----------------------+-------+--------------------------------+ | signature_invalid | 1 | a signature does not verify, | | | | the algorithm is not on the | | | | verifier's list, the algorithm | | | | differs from the one | | | | configured for the key, or | | | | DT_0 is not under a trusted | | | | root key | +-----------------------+-------+--------------------------------+ | par_hash_mismatch | 2 | a child's commitment does not | | | | match the parent presented | | | | with it | +-----------------------+-------+--------------------------------+ | depth_invalid | 3 | a del_depth is out of sequence | | | | or the chain exceeds | | | | del_max_depth | +-----------------------+-------+--------------------------------+ | principal_altered | 3 | a token's "sub" differs from | | | | DT_0's | +-----------------------+-------+--------------------------------+ | not_narrower | 4 | a child's Authority is not | | | | subsumed by its parent's under | | | | rules 1, 2, 3, or 5 | Asor Expires 18 April 2027 [Page 17] Internet-Draft Agent Delegation Chain October 2026 +-----------------------+-------+--------------------------------+ | expired | 5 | a token is outside its | | | | validity window, or its expiry | | | | exceeds its parent's (rule 4) | +-----------------------+-------+--------------------------------+ | holder_binding_failed | 6 | the proof of possession is | | | | absent or invalid for this | | | | request | +-----------------------+-------+--------------------------------+ | revoked | 7 | a token in the chain is | | | | revoked | +-----------------------+-------+--------------------------------+ | status_unknown | 7 | a status reference is present | | | | and its current status cannot | | | | be established | +-----------------------+-------+--------------------------------+ | audience_mismatch | 8 | DT_n's "aud" does not identify | | | | the Enforcement Point | +-----------------------+-------+--------------------------------+ | scope_not_granted | 8 | the action's scope is not | | | | covered by DT_n's scopes | +-----------------------+-------+--------------------------------+ | ceiling_exceeded | 8 | the action violates a | | | | constraint of DT_n | +-----------------------+-------+--------------------------------+ | unknown_constraint | 8 | DT_n carries a constraint of a | | | | type the verifier does not | | | | implement | +-----------------------+-------+--------------------------------+ Table 2: Verification outcome names 6.3. Several Chains Reaching One Agent This document defines the verification of one chain. An agent may hold Delegation Tokens issued along more than one path from one or more roots, and so hold more than one chain. For each request the presenter presents one chain, the Enforcement Point verifies that chain alone, and the action is permitted only if that chain permits it. An Enforcement Point MUST NOT combine the Authority of tokens from different chains, and a chain that fails verification has no effect on the evaluation of another chain the same agent presents. A presenter holding several valid chains chooses which to present; one valid chain that permits the action suffices. [I-D.jackson-wimse-evaluation] treats the same situation from the verifier's side, in its rule that each delegation path is evaluated independently and fails closed on its own; this document cites that rule informatively and does not depend on it. Asor Expires 18 April 2027 [Page 18] Internet-Draft Agent Delegation Chain October 2026 6.4. Open Issue: Trust-Anchor Provenance Step 1 assumes the verifier already holds the trusted root key or keys. This document says nothing about how a verifier comes to hold that key, how the key is bound to the party it is trusted as, or under which algorithm that binding was made; the algorithm rule of step 1 reaches every token in the chain and stops at the root key. A chain can be post-quantum at every hop and still rest on a root key whose provenance the verifier cannot check. That is a property of every delegation chain design, not of this one, and the author's view is that it belongs to the working group rather than to this document. It is recorded here as open and is not solved here. 7. Holder Binding Every Delegation Token is sender-constrained by a "cnf" claim [RFC7800] carrying the JWK thumbprint of the holder's key, proven per request with DPoP [RFC9449]. mTLS-bound tokens [RFC8705] MAY be used where the transport is controlled end-to-end. A captured token is therefore unusable without its bound private key, which mitigates replay of intermediate tokens. The "cnf" claim is present in every token of a chain, and a Verifier that sees no request (Section 6.1) checks its presence and shape but cannot perform step 6. 8. Revocation Delegation Tokens are RECOMMENDED to be short-lived (seconds to minutes for leaf and execution tokens), so that expiry is the common revocation path. For earlier revocation of longer-lived delegations, each token MAY carry a Token Status List [I-D.ietf-oauth-status-list] reference; revoking a token's status entry, and by local policy the entries of its descendants, revokes a delegation or a whole sub-chain while preserving offline verification (the status list is itself cacheable and offline-checkable). An online revocation endpoint [RFC7009] MAY additionally be offered. Whether a token carries a status reference is decided at issuance. A token issued without one can be revoked only by expiry. A token issued with one is subject to step 7 of Section 6 as stated there: a cached answer is trusted for its time to live and no longer, and an answer that cannot be obtained or refreshed is unknown, which denies. A deployment chooses between the two at issuance with that consequence in view. Asor Expires 18 April 2027 [Page 19] Internet-Draft Agent Delegation Chain October 2026 Short lifetimes mean re-issuance. A parent that is re-issued is a new token instance (Section 5); its existing children are not invalidated by the re-issuance, and a deployment that wants them invalidated revokes the previous instance. The rate at which this happens is an operational property that Section 9.5 states. Deployments that require synchronous cascading revocation MAY issue and exercise Delegation Tokens through an online Delegation Server as specified by [I-D.sweeney-wimse-credential-delegation]. The server can evaluate current delegation-tree state and refuse a revoked root or descendant immediately. This online bridge complements, and does not replace, the offline verification algorithm in Section 6: an Enforcement Point that receives a chain MUST still verify its signatures, linkage, attenuation, depth, principal, and expiry. 9. Security Considerations 9.1. Parent tokens remain valid after attenuation Attenuation produces a new child token but does not, by itself, invalidate the parent. A party holding the parent still holds the parent's (broader) authority. This is mitigated by three mechanisms that MUST be considered together: (a) tokens are short-lived and holder-bound (Section 7), so a leaked parent is both time-boxed and non-replayable without its key; (b) the "par_hash" byte-commitment (Section 5) prevents splicing a child onto a different parent; and (c) status-list revocation (Section 8) allows early invalidation of a parent and its subtree. Deployments that require immediate parent invalidation on delegation MUST use short TTLs and status lists accordingly. 9.2. Chain splicing Without the byte-commitment, an attacker could present a valid child together with a broader token as its purported parent. Step 2 of Section 6 prevents this: the child's "par_hash" digests the parent's exact Signing Input, so only the intended parent verifies. The same check is what denies a child presented with a re-issued parent rather than the instance it was issued under (Section 5). 9.3. Confused deputy and over-broad delegation Because each hop's authority is the meet of parent and request (Section 4.3), a child cannot be induced (e.g. by prompt injection) to exercise authority the parent lacked. The principal invariance check (step 3 of Section 6) adds that a child cannot be induced to act under a different grant than its parent: a token that names another Principal is not a member of the chain. Asor Expires 18 April 2027 [Page 20] Internet-Draft Agent Delegation Chain October 2026 9.4. Unbounded depth, fan-out, and aggregate budgets "del_max_depth" (checked in step 3) bounds chain length; deployments SHOULD set it low (e.g. 5). Fan-out (a parent delegating to many children) is not limited by the token format and MUST be bounded by the issuing infrastructure if required. Quantity constraints compose across siblings, and subsumption is checked per edge. A "max" constraint bounds one authorized action and nothing else (Section 4.2). A parent holding {"key": "max_spend", "max": 100} can mint any number of children each carrying max_spend 100; every parent-child edge satisfies C <= P, and a subtree of N children can spend N x 100. The same holds at a single enforcement point and across several: against a root ceiling of 100, two valid children can each authorize 60 at two different gateways; both chains verify, each gateway sees a request within bound, and the combined spend is 120. Individually permitted delegations compose into an outcome nobody permitted. The "max_subtree" type names that total, and a chain-only verifier checks only that a child's "max_subtree" is no wider than its parent's; verification is side-effect free by design, so a signed ceiling names a limit while nothing in verifying it reserves against that limit or sees another gateway's balance. A signed ceiling alone provides none of the protection an aggregate budget needs. An aggregate budget over a consequential resource therefore needs machinery outside the token, and that machinery has two separable parts. Allocation -- deciding how much of a parent's budget each child may consume -- requires coordination: an allocator that splits a budget at delegation time only keeps the total under bound if it is a single writer, since two issuers allocating offline from the same budget can each allocate the same units. Spending afterwards does not require coordination once allocations are disjoint: each enforcement point debits its own durable balance for the allocation it holds and contacts no shared service per action. Two deployment shapes follow, and a deployment that enforces aggregate budgets uses one of them: * Shared accounting: one ledger, consulted by every enforcement point, that checks and debits atomically at authorization time. A ledger that is read at authorization and debited afterwards, or debited by more than one writer without coordination, does not close the hole; the check and the debit are one operation or the budget is not enforced. An online Delegation Server through which every action is exercised, as in [I-D.sweeney-wimse-credential-delegation], is one place such accounting can be held. Asor Expires 18 April 2027 [Page 21] Internet-Draft Agent Delegation Chain October 2026 * Coordinated allocation with local enforcement: a single-writer allocator reserves disjoint allocations for the children (for example 60 units to the child acting at gateway A and 40 to the child acting at gateway B, leaving none at the parent, since allocating to a child reduces what remains available to the parent), and each enforcement point enforces its own allocation locally against a durable balance. This path has to protect against three hazards that a signed ceiling does not: duplicate allocation of the same units to two children; local rollback, where an enforcement point loses or reverts a debit it has already honored; and premature reuse of allocated units before the action that consumed them is settled. Either way, the division is the one this document is built on: the offline chain bounds each action and produces the audit trail; the online half holds the aggregates. 9.5. Offline verification vs. revocation latency Offline verification means an enforcement point may honor a token that has been revoked but whose status-list update it has not yet fetched. Deployments trade this window against TTL: shorter TTLs bound the exposure, and step 7 of Section 6 fixes the window at the cached answer's time to live. This is the standard status-list trade-off and MUST be documented for each deployment. The lifetimes Section 8 recommends have a second cost, which is on the issuing side rather than the verifying side. A token that lives for seconds to minutes and is still needed must be re-issued, so a platform with many live agent instances sustains a refresh rate proportional to the number of live instances, continuously, not only at startup. That rate is a property of the deployment and a deployment MUST size its authorization server for it, and for the resynchronisation case in which many instances refresh at once after an outage of the issuer or of the network between them. Offline verification is preserved under these lifetimes; offline operation is not, because an agent whose issuer is unreachable stops receiving tokens when its current ones expire. Asor Expires 18 April 2027 [Page 22] Internet-Draft Agent Delegation Chain October 2026 The refresh rate counts every token in a chain, not only the roots, and grows with fan-out. Rule 4 of Section 4.3 and step 5 of Section 6 cap a child's "exp" at its parent's when the child is issued, so at the recommended lifetimes every child that keeps working is re-issued at least once per parent lifetime, whichever instance of the parent it commits to (Section 5). A deployment that revokes the previous parent instance at refresh adds a burst on top of that rate: every child of that instance at once. Both the sustained rate and the burst belong in the sizing above, and the fan- out bound of Section 9.4 is what bounds them. 9.6. Why not macaroons; algorithm agility Macaroons [Macaroons] verify with the root secret, precluding public offline verification at an untrusted edge; this document uses public- key signatures. Algorithms are fully specified [RFC9864] and agile via the JOSE "alg" registry, with a migration path to ML-DSA [RFC9964]. The algorithm list of step 1 in Section 6 is the agility mechanism on the verifying side. A deployment that retires an algorithm, for example a quantum-vulnerable one after a transition date, removes it from the verifier's list, and chains that still use it are then denied whatever their remaining lifetime. Because every hop's "alg" sits in a protected header that the child's "par_hash" covers, a verifier holding the full chain sees every hop's algorithm, and a parent whose algorithm was swapped after the fact no longer matches its child's commitment. 9.7. Root issuance is the policy decision point DT_0's Authority is asserted by whoever holds the root key. Every guarantee in this document begins downstream of that minting: each child is a deterministic attenuation of DT_0, and verification can establish that no hop exceeded the root, never that the root was right. Approval policy therefore belongs at root issuance. A deployment that requires a human decision before an agent may act with consequential authority places that decision where DT_0 is minted, not at a later hop, because no later hop can widen what DT_0 granted and no verification step can tighten it. The Principal named in DT_0's "sub" is the party that decision is taken on behalf of, and the "client_id" of each hop records which agent acted under it. 10. IANA Considerations This document requests registration, in the JSON Web Token Claims registry, of: "del_depth", "del_max_depth", and "par_hash" (with the semantics in Section 3). The claims "sub", "client_id", "aud", and "cnf" are already registered and are used with their registered meanings as profiled in Section 3. Asor Expires 18 April 2027 [Page 23] Internet-Draft Agent Delegation Chain October 2026 It requests a new "Agent Delegation Constraint Types" registry with the following initial entries, each recorded with its measurement scope: "max" (per action), "max_lifetime" (per token lifetime), "max_subtree" (per subtree), "min" (per action), "one_of" (per action), "not_one_of" (per action), "prefix" (per action), and "rank" (per action). The registration policy is Specification Required; a registration states the type's value shape, its measurement scope, and its subsumption rule in the form of Section 4.3. Unknown types fail closed per Section 4.2. This document does not request registration of an "authorization_details" type value. [RFC9396] maintains no registry of type values, and recommends a collision-resistant namespace under the designer's control; see Section 4.4. 11. Implementation Status This section records the status of known implementations of this document at the time of its posting, as described in [RFC7942]. The description of implementations here is intended to assist the IETF in its decision processes in progressing drafts to RFCs. It is not an endorsement of any implementation, and the listing is not a claim that any implementation conforms to this revision in full. Please note that this section is to be removed before this document is published as an RFC. Two reference implementations are maintained by the author under the Apache License 2.0: "attenu-guard", in Python, which mints Delegation Tokens and runs the verification algorithm of Section 6, and "attenu- guard-ts", in TypeScript, which runs the verification algorithm and mints nothing. At the time of posting, both released libraries (attenu-guard 0.20.0 and attenu-guard-ts 0.14.0) implement this revision as an opt-in profile beside the previous one, which remains their default: the claim rules of Section 3 at parse, the accepted- algorithm list of step 1, principal invariance, the three-form scope grammar, the two cumulative constraint types with their totals supplied through a channel separate from the request, the "order" member of "rank", one constraint per (key, type), the closed detail and constraint objects, and the audience check of step 8, under a single-signer trust model. Both check the presence and shape of "cnf" and perform neither step 6 (holder binding) nor step 7 (status list), which both document as not performed. The vector set of Appendix B for this revision has thirty-five files; the Python library generates and scores it on every test run, and the TypeScript library vendors it byte for byte and scores it in its test suite. The previous revision's twenty files ship in both libraries unchanged. Asor Expires 18 April 2027 [Page 24] Internet-Draft Agent Delegation Chain October 2026 Two implementations independent of the author's code have run the twenty test vectors of the previous revision and published their results, as reported by their authors: the conformance harness of the Cred delegation protocol, whose published result of 2026-10-07 reports 20 of 20, with no failures and no declared gaps, at a pinned commit of the Cred SDK; and a standalone Node.js verifier that imports no code from either reference implementation, which reported 20 of 20 with verdicts and declared reasons both matching, under the boundary its author states: the vectors' HS256 single-signer, public- test-key profile, and steps 1 to 5 only. Neither result is reproduced here, and neither author has reported a run against the vectors of this revision. 12. References 12.1. Normative References [I-D.ietf-oauth-status-list] Looker, T., Bastian, P., and C. Bormann, "Token Status List (TSL)", Work in Progress, Internet-Draft, draft-ietf- oauth-status-list-21, 21 June 2026, . [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, . [RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", STD 68, RFC 5234, DOI 10.17487/RFC5234, January 2008, . [RFC6749] Hardt, D., Ed., "The OAuth 2.0 Authorization Framework", RFC 6749, DOI 10.17487/RFC6749, October 2012, . [RFC7515] Jones, M., Bradley, J., and N. Sakimura, "JSON Web Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, May 2015, . [RFC7519] Jones, M., Bradley, J., and N. Sakimura, "JSON Web Token (JWT)", RFC 7519, DOI 10.17487/RFC7519, May 2015, . Asor Expires 18 April 2027 [Page 25] Internet-Draft Agent Delegation Chain October 2026 [RFC7800] Jones, M., Bradley, J., and H. Tschofenig, "Proof-of- Possession Key Semantics for JSON Web Tokens (JWTs)", RFC 7800, DOI 10.17487/RFC7800, April 2016, . [RFC8032] Josefsson, S. and I. Liusvaara, "Edwards-Curve Digital Signature Algorithm (EdDSA)", RFC 8032, DOI 10.17487/RFC8032, January 2017, . [RFC8037] Liusvaara, I., "CFRG Elliptic Curve Diffie-Hellman (ECDH) and Signatures in JSON Object Signing and Encryption (JOSE)", RFC 8037, DOI 10.17487/RFC8037, January 2017, . [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, . [RFC8785] Rundgren, A., Jordan, B., and S. Erdtman, "JSON Canonicalization Scheme (JCS)", RFC 8785, DOI 10.17487/RFC8785, June 2020, . [RFC9068] Bertocci, V., "JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens", RFC 9068, DOI 10.17487/RFC9068, October 2021, . [RFC9396] Lodderstedt, T., Richer, J., and B. Campbell, "OAuth 2.0 Rich Authorization Requests", RFC 9396, DOI 10.17487/RFC9396, May 2023, . [RFC9449] Fett, D., Campbell, B., Bradley, J., Lodderstedt, T., Jones, M., and D. Waite, "OAuth 2.0 Demonstrating Proof of Possession (DPoP)", RFC 9449, DOI 10.17487/RFC9449, September 2023, . [RFC9728] Jones, M.B., Hunt, P., and A. Parecki, "OAuth 2.0 Protected Resource Metadata", RFC 9728, DOI 10.17487/RFC9728, April 2025, . [RFC9864] Jones, M.B. and O. Steele, "Fully-Specified Algorithms for JSON Object Signing and Encryption (JOSE) and CBOR Object Signing and Encryption (COSE)", RFC 9864, DOI 10.17487/RFC9864, October 2025, . Asor Expires 18 April 2027 [Page 26] Internet-Draft Agent Delegation Chain October 2026 12.2. Informative References [Biscuit] "Biscuit Authorization Token Specification, v3", n.d., . [I-D.coetzee-oauth-spt-txn-tokens] Coetzee, R. J., "Transaction-Bound Authorization Tokens for Software and AI Agents (SPT-Txn)", Work in Progress, Internet-Draft, draft-coetzee-oauth-spt-txn-tokens-03, 19 July 2026, . [I-D.hamr-oauth-agent-delegation] Hassan, A., "An Attenuated Delegation Profile for Automated Agents", Work in Progress, Internet-Draft, draft-hamr-oauth-agent-delegation-02, 20 September 2026, . [I-D.ietf-oauth-identity-chaining] Schwenkschuster, A., Kasselman, P., Burgin, K., Jenkins, M. J., Campbell, B., and A. Parecki, "OAuth Identity and Authorization Chaining Across Domains", Work in Progress, Internet-Draft, draft-ietf-oauth-identity-chaining-17, 19 July 2026, . [I-D.ietf-wimse-aims] Kasselman, P., Lombardo, J., Rosomakho, Y., Campbell, B., Steele, N., and A. Parecki, "AI Identity Management System", Work in Progress, Internet-Draft, draft-ietf- wimse-aims-00, 15 September 2026, . [I-D.ietf-wimse-identifier] Rosomakho, Y. and J. A. Salowey, "Workload Identifier", Work in Progress, Internet-Draft, draft-ietf-wimse- identifier-03, 6 July 2026, . Asor Expires 18 April 2027 [Page 27] Internet-Draft Agent Delegation Chain October 2026 [I-D.jackson-wimse-evaluation] Jackson, W., "Verifier-Side Evaluation Semantics for Delegated Authority Chains", Work in Progress, Internet- Draft, draft-jackson-wimse-evaluation-04, 10 October 2026, . [I-D.niyikiza-oauth-attenuating-agent-tokens] Aimable, N., "Attenuating Authorization Tokens for Agentic Delegation Chains", Work in Progress, Internet-Draft, draft-niyikiza-oauth-attenuating-agent-tokens-01, 15 June 2026, . [I-D.reece-wimse-cross-org-delegation] Reece, M., "Cross-Organizational Delegation for Workload and Agent Identity: Problem Statement and Requirements", Work in Progress, Internet-Draft, draft-reece-wimse-cross- org-delegation-02, 31 August 2026, . [I-D.sweeney-wimse-credential-delegation] Sweeney, K., "Credential Delegation Protocol for AI Agents in Multi-System Environments", Work in Progress, Internet- Draft, draft-sweeney-wimse-credential-delegation-01, 13 October 2026, . [Macaroons] "Macaroons: Cookies with Contextual Caveats for Decentralized Authorization in the Cloud", NDSS 2014 , 2014. [RFC2693] Ellison, C., Frantz, B., Lampson, B., Rivest, R., Thomas, B., and T. Ylonen, "SPKI Certificate Theory", RFC 2693, DOI 10.17487/RFC2693, September 1999, . [RFC7009] Lodderstedt, T., Ed., Dronia, S., and M. Scurtescu, "OAuth 2.0 Token Revocation", RFC 7009, DOI 10.17487/RFC7009, August 2013, . [RFC7942] Sheffer, Y. and A. Farrel, "Improving Awareness of Running Code: The Implementation Status Section", BCP 205, RFC 7942, DOI 10.17487/RFC7942, July 2016, . Asor Expires 18 April 2027 [Page 28] Internet-Draft Agent Delegation Chain October 2026 [RFC8693] Jones, M., Nadalin, A., Campbell, B., Ed., Bradley, J., and C. Mortimore, "OAuth 2.0 Token Exchange", RFC 8693, DOI 10.17487/RFC8693, January 2020, . [RFC8705] Campbell, B., Bradley, J., Sakimura, N., and T. Lodderstedt, "OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens", RFC 8705, DOI 10.17487/RFC8705, February 2020, . [RFC9964] Prorock, M. and O. Steele, "ML-DSA for JSON Object Signing and Encryption (JOSE) and CBOR Object Signing and Encryption (COSE)", RFC 9964, DOI 10.17487/RFC9964, May 2026, . Appendix A. Acknowledgments This work builds directly on, and seeks convergence with, [I-D.niyikiza-oauth-attenuating-agent-tokens], [I-D.coetzee-oauth-spt-txn-tokens], [I-D.sweeney-wimse-credential-delegation], [I-D.ietf-wimse-aims], and the requirements of [I-D.reece-wimse-cross-org-delegation]. The capability-token lineage of [Macaroons], [Biscuit], and [RFC2693] is gratefully acknowledged. The "min" constraint type was added after Amr Hassan, author of [I-D.hamr-oauth-agent-delegation], observed that -00 had no comparator for a floor tightened upward; the duration-typed "tenureMin" axis of that document is the motivating example. The following contributions were made in review of the -01 and shaped this revision. Naming a contributor records where their contribution landed; it does not imply that they endorse this document. Wes Jackson: the binding of the chain to an accountable Principal in "sub", distinct from the holder key, and the naming of the Acting Agent at each hop in "client_id" (Section 3, Section 3.1); the observation that quantity constraints compose across siblings while subsumption is checked per edge, that "max" is therefore per token, and that per-action, per-lifetime, and per-subtree limits are enforced by different machinery and belong in distinct registered types (Section 4.2, Section 9.4); the atomic check-and-debit requirement on shared accounting and the single-writer constraint on delegation-time allocation (Section 9.4); root issuance as the policy decision point (Section 9.7); the scope-vocabulary limit (Section 4.5); the questions that led to the process-every-detail rule and the per-type interoperability statement (Section 4.4); and the per-path evaluation rule answered in Section 6.3. Asor Expires 18 April 2027 [Page 29] Internet-Draft Agent Delegation Chain October 2026 Iman Schrock: the two-gateway example in which two verified chains overspend a root ceiling, the distinction between allocation, which needs coordination, and spending within disjoint allocations, which does not, the two deployment shapes and the three hazards of the allocation path (Section 9.4), the compatibility point that led the scope grammar to keep structured literals as their own form, and the request to state the residual ambiguity of that grammar beside it (Section 4.1). Girish Konda: the sustained refresh rate implied by the recommended lifetimes and the sizing it requires of the authorization server, and the requirement that a verifier tell a fresh status answer from a stale one (Section 9.5, Section 6 step 7). Jijie Wei: the question of what "par_hash" commits to when a parent is re-issued, answered in Section 5, and the counting of child re- issuance in the refresh rate (Section 9.5). Kieran Sweeney: the proposal to admit scope strings issued by OAuth providers, which became the opaque scope form, and the vectors that exercise it (Section 4.1, Appendix B). Venkata Karunakar Uppalapati: the rule that a verifier rejects a chain carrying an algorithm outside its local policy even where the signature verifies, now step 1 of Section 6 and the agility text in Section 9, and the trust-anchor provenance gap recorded in Section 6.4. Appendix B. Reference Implementation and Test Vectors A permissively licensed reference implementation (the "attenu-guard" library) and a set of offline-verification test vectors (chains that MUST verify and adversarial chains that MUST be rejected, each with the outcome name of Section 6.2 it is expected to produce) are published with this draft. They are intended for interoperability testing across independent implementations. The twenty vector files published with the -01 are unchanged by this revision and remain available under their -01 names: independent implementations have vendored them, and a byte-stable set is worth more than a corrected one. They do not conform to this revision: their tokens carry no "cnf" and no "client_id", and their "aud" is null. The vector set published with this revision is a second, separately named set. It carries "cnf", "client_id", and a well- formed "aud" on every token, and adds vectors for: a chain in which a child's "sub" differs from the root's (principal_altered); a child presented with a re-issued parent rather than the instance it commits to (par_hash_mismatch); a wildcard scope over an opaque child scope Asor Expires 18 April 2027 [Page 30] Internet-Draft Agent Delegation Chain October 2026 and an opaque scope over a wildcard child, both not_narrower, and an opaque scope covering a byte-identical child, which verifies, contributed by Kieran Sweeney; a detail carrying two constraints with the same key and type (malformed); a "rank" whose "order" differs from its parent's (not_narrower); a "max_lifetime" under a parent "max" of the same key (not_narrower, by the no-cross-type rule); a token whose "alg" is not on the verifier's list (signature_invalid); and a token carrying an authorization detail of a type the verifier does not implement (malformed). The -01 set's coverage of scope and ceiling widening, parent splicing, depth and expiry violations, wildcard errors, RFC 8785 number and string forms, non-finite values, duplicate member names, and the informational "c14n" label is re- minted in the new set under this revision's claim layout. Appendix C. Changes Since -01 * "sub" is defined as the Principal, identical at every hop; "client_id" is added to the required claims as the Acting Agent at each hop; and step 3 of the verification algorithm denies a chain in which any token's "sub" differs from the root's. A new subsection explains the split. * "aud" is required to be a string or non-empty array of strings; null is malformed. The audience check of RFC 9068 Section 4 is applied to the leaf token in step 8. * Step 1 requires a verifier-held list of accepted algorithms, denies any token whose "alg" is not on it even where the signature verifies, and takes the algorithm from the verifier's configuration for the key rather than from the header. The algorithm agility text says how an algorithm is retired. * The scope grammar gains a third form, "opaque-scope", the RFC 6749 scope token without the asterisk, so that provider-issued scope strings can be carried; classification is by bytes alone in a stated order; an opaque scope covers only a byte-identical child and no wildcard covers it; the residual ambiguity for dotted provider strings is stated beside the grammar. * Two constraint types are added, "max_lifetime" and "max_subtree", so that per-action, per-lifetime, and per-subtree bounds are distinct registered types; "max" is defined as per action only; no inference is made across types; a chain-only verifier checks only that a child's cumulative bounds are no wider than its parent's. * The "rank" type carries its ordering on the wire in an "order" member, and a child's ordering must be identical to its parent's. Asor Expires 18 April 2027 [Page 31] Internet-Draft Agent Delegation Chain October 2026 * A detail may not carry two constraints with the same key and type; a verifier rejects a token that does. * Three closure rules are stated as MUSTs: a token carries exactly one "agent_delegation" detail; that detail carries no members other than "type", "scopes", and "constraints"; and a constraint object carries no members other than "key", its type member, and the members its type defines. A token that breaks any of them is malformed. * The covering relation is bound to the authorization detail type; a verifier must evaluate every detail or reject the token, and an unimplemented type is a rejection; under this revision a token carries exactly one detail, of type "agent_delegation", and chains carrying several types are left to a later revision; a resource server is pointed to RFC 9728 to declare the types it supports. * The IANA request for an "authorization_details" type value is withdrawn, since RFC 9396 keeps no such registry; whether the type value becomes a URI is recorded as open. * The scope-vocabulary limit is recorded as an open issue in its own subsection, with the interface a companion document is expected to meet and the rule under which such a document is cited. * The chain linkage section states that "par_hash" commits to a parent token instance, and what that means for re-issued parents and their children. * Step 8 denies an action under a cumulative constraint when no component holds the running total it is measured over. * An integer whose magnitude exceeds 2^53-1 is malformed. * The revision states that it defines no transition mode for chains shaped by the previous revision. * Step 7 states that a cached status answer is trusted for its time to live, that an unobtainable or unrefreshable status is unknown and denies, and that a token issued without a status reference is a choice made at issuance. * A table states what a verifier that sees no request may and may not conclude, and a table names the verification outcomes the test vectors use. * Several chains reaching one agent are addressed: each chain is verified alone and never combined with another. Asor Expires 18 April 2027 [Page 32] Internet-Draft Agent Delegation Chain October 2026 * Trust-anchor provenance is recorded as an open issue. * The fan-out security consideration gains the sibling and two- gateway examples, the allocation/spending distinction, the two deployment shapes for aggregate budgets, and the three hazards of the allocation path. * The revocation-latency security consideration gains the sustained refresh rate, the resynchronisation case, the sizing requirement, the counting of child re-issuance, and the revoke-at-refresh burst. * Root issuance is stated as the policy decision point in a new security consideration. * draft-klrc-aiagent-auth, now replaced, is re-pointed to draft- ietf-wimse-aims in the introduction and the acknowledgments; draft-jackson-wimse-evaluation, draft-ietf-wimse-identifier, RFC 6749, RFC 7942, and RFC 9728 are added as references. * An Implementation Status section is added. * The test-vector appendix records that the -01 set stays byte- stable and does not conform to this revision, and describes the second set that does. * Step 8 and the constraint vocabulary state that a running total reaches a cumulative constraint through a channel separate from the request, that cumulative and per-action constraints are evaluated against different inputs, and that a per-action "max" on a running count bounds nothing. Author's Address Rafael Asor Attenu Email: rafael.asor@gmail.com URI: https://attenu.io/ Asor Expires 18 April 2027 [Page 33]