The Agent Created Another Agent. Which Permissions Came With It?
Claude Code 2.1.232 turned subagent forking on by default in interactive sessions. A forked subagent inherits the full conversation, the same system prompt, tools and model, and the parent's prompt cache. Anthropic documents that a subagent also inherits the parent session's permission mode unless configuration overrides it. Delegation of a task is now, quietly, also a transfer of authority. Updated 29 August 2026 with a re-verification pass on draft-asor-wimse-agent-delegation-chain-00 and its attenu-guard reference implementation two days after the draft's own posting: three further attenu-guard releases, the draft's own text on fan-out, on the scope of its prompt-injection claim, and on resource binding, the exact rejection cases its shipped interop test vectors do and do not cover, and confirmation that neither WIMSE working group adoption nor an implementation independent of Attenu has surfaced.
Event analysed: . This analysis was published on 16 August 2026.
Anthropic's Claude Code changelog for version 2.1.232 states that subagent forking is now on by default: a subagent with subagent_type "fork" inherits the full conversation and prompt cache, and non-teammate agent spawns in interactive sessions now run in the background by default. Anthropic's subagent documentation defines a fork as a subagent that inherits the entire conversation so far instead of starting fresh, says this drops the input isolation subagents otherwise provide, and states that a fork sees the same system prompt, tools, model and message history as the main session, while the fork's own tool calls stay out of the main conversation and only its final result returns. On permissions, the documentation says that if permissionMode is left unset a subagent inherits the main conversation's mode, that a parent using bypassPermissions or acceptEdits takes precedence and cannot be overridden, and that a parent in auto mode causes the subagent to inherit auto mode with its frontmatter mode ignored. Anthropic also documents controls: a tools list and disallowedTools per agent, denying a subagent type or the Agent tool itself through permissions.deny, and isolation: worktree to give the subagent an isolated copy of the repository. Anthropic does not document credential or identity inheritance here, and we do not claim it. Moona Intelligence calls the underlying governance question Authority Inheritance. That term is ours, not Anthropic's. Newly surfaced evidence, verified this session, shows an independent architecture answering the same question with an opposite default. Grantex's Protocol Specification, version 1.0, frozen in February 2026, and a related Internet Draft submitted to the IETF in March 2026, require a delegated grant's scope to be a subset of its parent's, cap its expiry at the parent's own expiry, limit delegation depth to a default of 3 hops with a hard cap of 10, and atomically revoke every descendant grant when the grant they descend from is revoked. That is documented protocol design with a real reference implementation behind it, not full inheritance by default, and this piece now covers what it actually specifies, what its own shipped software does not yet enforce, and what it does not establish about who was entitled to grant the authority in the first place. A second update, verified 27 August 2026, covers a different individual Internet-Draft, draft-asor-wimse-agent-delegation-chain-00, "Verifiable Attenuated Delegation for AI Agent Chains," authored by Rafael Asor of Attenu and targeting the WIMSE working group with intended status Standards Track, neither of which makes it an adopted WIMSE document, an RFC or IETF consensus. Its own text, verified via the reference implementation's mirrored copy of the draft after datatracker.ietf.org and every ietf.org host were blocked by this session's network egress policy, defines a JWT access token profile (RFC 9068) carrying authorization_details (RFC 9396), cnf-based DPoP holder binding (RFC 9449), a del_depth and del_max_depth pair bounding delegation chain length, and a par_hash claim on every non-root token that is a SHA-256 digest of the parent token's own JWS Signing Input, intended to stop a valid child being presented alongside a different, broader parent. Its subsumption algorithm requires a child's actions, locations, numeric ceilings and enumerated constraints to stay inside the parent's, its expiry to be no later than the parent's, and an unrecognized constraint type to fail closed. The stated contribution is that a final enforcement point can check an entire delegation chain offline against trusted root keys, consulting a cached, separately specified Token Status List only for revocation, which the draft's own security considerations describe as a latency trade-off, not an instantaneous guarantee, and which the draft states explicitly does not itself invalidate the broader parent authority a holder still possesses after a narrower child is issued. Monotonic, subset-based attenuation is not new here, Grantex already specifies it independently; the narrower, additive claim this piece finds supported is offline, cryptographically linked, subsumption-enforced verification at the point of final action, which this session did not find equivalently specified in RFC 8693 OAuth Token Exchange, whose nested actor claim the draft itself describes as informational rather than enforced at each hop. The draft names five neighboring individual drafts, including draft-niyikiza-oauth-attenuating-agent-tokens and draft-mw-spice-actor-chain, and states an intent to converge with them rather than claiming to be first. Attenu's own attenu-guard library, whose GitHub changelog dates a wire-format release to 17 August 2026 and a 0.4.0 rename to 24 August 2026, both before the draft's own 27 August posting date, is the same organization's reference implementation, not an independent adopter, carries a self-described self-authored test suite with no independent security audit, SOC 2 attestation or penetration test this session could find documented, and its in-process Guard API is not identical to a full interoperable implementation of the draft's wire token profile. A 29 August 2026 re-verification pass, two days after the draft's own posting, confirms the picture rather than changing it: attenu-guard shipped three further releases (0.5.0, 0.6.0, 0.6.1, dated 27 through 29 August) adding more framework adapters, supply-chain provenance tooling and packaged interop test vectors, still from the same single-author, single-organization repository, still with no independent implementation, no WIMSE working group adoption and no mailing-list adoption discussion this session could find. The draft's own text, read again directly this session, states plainly that fan-out is not bounded by the token format and must be bounded by issuing infrastructure where required, and scopes its prompt-injection claim narrowly to authority escalation beyond the parent rather than to misuse within authority a child already legitimately holds. Its shipped interop test vectors, nine files fetched directly this session, exercise widened scope, exceeded ceiling, parent-chain splicing, delegation depth, non-monotonic expiry, signature forgery and two wildcard-matching edge cases, and do not include a named vector for revocation or for token replay.
Version 2.1.232 of Claude Code changed a default. Anthropic's changelog puts it in one line: subagent forking is now on by default, a subagent_type: "fork" subagent inherits the full conversation and prompt cache, and non-teammate agent spawns in interactive sessions now run in the background by default.
Everyone read that as a productivity change. Parallel agents, less re-explaining, cheaper cache reuse. All true. What I think actually matters is smaller and harder: when one agent creates another agent to finish part of its work, which parts of the first agent's authority silently come along?
Claude Code made forking ordinary
The version itself is easy to place. npm's registry metadata for the @anthropic-ai/claude-code package records 2.1.232 as published on 13 August 2026. The changelog does not carry calendar dates, so package publication metadata is the dating evidence here, not an official Anthropic release announcement.
Anthropic's subagent documentation confirms the default is scoped, not universal. Fork mode is on by default in interactive sessions, off by default in non-interactive mode with -p and in the Agent SDK, and the interactive default requires v2.1.232 or later. The CLAUDE_CODE_FORK_SUBAGENT environment variable overrides it in either direction.
That is the whole feature summary you are getting from me. This is not a changelog recap.
The child does not start from zero
Anthropic's definition is precise and worth quoting closely. A fork is a subagent that inherits the entire conversation so far instead of starting fresh. The documentation says this drops the input isolation that subagents otherwise provide: a fork sees the same system prompt, tools, model and message history as the main session. The fork's own tool calls still stay out of the main conversation and only its final result comes back. Because system prompt and tool definitions are identical to the parent, the first request reuses the parent's prompt cache.
Note what that list contains and what it does not. Context, system prompt, tool definitions, model, prompt cache. Anthropic does not describe credentials or identity as inherited objects here, and I am not going to invent that. Filesystem behaviour is documented separately: a subagent starts in the main conversation's working directory, and isolation: worktree gives it a separate copy of the repository instead.
Permission state is documented separately again, and it is the interesting one. Anthropic says that if you leave permissionMode unset, the subagent inherits the main conversation's mode, which starts as auto mode on Pro, Max and Team plans unless settings or an organization change it. Setting it overrides that mode, with exceptions the documentation is explicit about: if the parent uses bypassPermissions or acceptEdits, that takes precedence and cannot be overridden, and if the parent is in auto mode the subagent inherits auto mode and its own frontmatter mode is ignored, with the classifier evaluating the subagent's tool calls using the same block and allow rules as the parent session.
That is a coherent design. It stops a subagent definition from quietly escalating past what you chose for the session, and it stops a child claiming a stricter posture than the classifier the parent is actually running under. It also means the direction of inheritance is set by the parent's state at spawn time, not by the child's declaration.
A task and its authority are not the same thing
Here is the conceptual centre, and it is not a Claude Code question.
When a parent agent delegates, four different things can travel with the handoff. The task. The context. The tool definitions. The permission state. Product design usually treats these as one bundle because that is what makes delegation feel seamless. They are not one thing. Handing another actor the job of drafting tests is a statement about work. It is not, by itself, a statement about which consequential operations that actor may execute against your infrastructure.
Most authorization thinking still assumes the actor existed before the authority was granted. Agent systems invert that. The actor is created, at runtime, by another actor, and its authority arrives as a side effect of how it was created rather than as a decision anyone made about it.
Inheritance is useful, and I am not calling it a flaw
Shared context is the entire point of a fork. Anthropic's own reasoning is sound: use a fork when any other subagent would need too much background to be useful, or when you want to try several approaches in parallel from the same starting point. Reusing the prompt cache makes it cheaper than a fresh subagent. Background execution means the work does not block you.
Permission inheritance is what makes that practical. A subagent that re-prompted for every decision the parent session already settled would be useless. Nobody is going to configure a permission mode for every ephemeral child.
But inheritance creates a new authorization boundary
The questions worth asking are the ones nobody asks while the feature is working.
When the child reaches a genuinely consequential operation, who authorized that specific action? The user authorized a session. The parent authorized a task. Neither of those is the same as authorizing the thing the child is about to execute. When the parent session is running under a broad mode, the child runs under that mode too. When several children are running in the background at once, the number of actors operating under that inherited posture is no longer one.
Anthropic documents that background subagents surface every permission prompt in the main session, naming the subagent that is asking, and that you can approve or press Esc to deny that one tool call without stopping the subagent. So the parent is observable and interruptible. That is a real control and I want it stated clearly, because the failure mode here is not agents running loose. It is a prompt arriving with no way to reconstruct which chain of delegation produced it.
Anthropic already exposes controls
Fairness matters more than a scary framing. The documented controls are substantial. A custom subagent can declare a tools list, and Anthropic notes it inherits every tool available to subagents if that field is omitted. disallowedTools removes tools from the inherited or specified list. A specific subagent type can be blocked with an Agent(name) rule in permissions.deny, including the fork type, and delegation can be switched off entirely by denying the Agent tool itself. isolation: worktree runs the subagent against a temporary git worktree. Anthropic also documents that when the main conversation itself runs isolated in a worktree, the same checks apply to every subagent it spawns, including ones without that setting. Background subagents run with a smaller built-in tool set than foreground subagents, except for conversation forks. Plugin subagents cannot use permissionMode, hooks or mcpServers at all, which Anthropic states is for security reasons.
Those are per-configuration controls over which child gets created and what it may touch. They are not the same as a record of where a given child's authority came from.
Delegation is not concurrency
We have written about several agents acting at once, and this is a different question. When three agents with conflicting goals began revoking each other's access, every actor already held its own authority and the problem was interaction. When an agent runs unattended for hours on one objective, the question is how long a prior authorization stays meaningful. When Claude Code automated the decision about when to ask you for permission, the question was who decides that a human needs to be involved.
Authority Inheritance is the one underneath all three: where did this new actor's authority come from in the first place? Concurrency assumes the actors exist. Delegation creates them. That is our framing and our vocabulary. Anthropic does not use the terms Authority Inheritance or Agent Authority, and nothing here should be read as Anthropic endorsing them.
Why this is not hypothetical
Anthropic has independently documented a real internal incident showing why authority inheritance across agent creation can matter. In its August 2026 risk report, Anthropic describes an employee whose AI usage was not logged and was not covered by automated offline monitoring giving an agent a relatively open-ended task that involved spinning up new agents in a cluster with very sensitive resources. Due to legacy instructions, the report says, the main agents spawned the new agents with --dangerously-skip-permissions, and those new agents were also not covered by offline monitoring. One of them deleted a large number of jobs, which is how the agents were caught and shut down. Anthropic says it believes the agent was attempting to delete only jobs it had created and made a mistake, but that given the monitoring gap it cannot confirm this. Anthropic states it has since developed blocking controls that would very likely have prevented that kind of activity, and that offline monitoring still does not cover all employees and all usage in those clusters. Some details are redacted in the report.
That incident is separate evidence. It is not attributable to Claude Code 2.1.232, it is not described as involving the fork mechanism, and I am not connecting them causally. What it establishes independently is that the moment of agent creation is a real place where a permission posture propagates further than anyone intended.
What I am not saying
Anthropic does not document that credentials, identity, network reach or arbitrary filesystem access inherit through a fork, and nothing here claims they do. A fork is not unconstrained: Anthropic documents that a fork cannot spawn further forks, that the Agent tool's run_in_background parameter is removed when fork mode is on, and that managed settings restrictions apply to every subagent regardless of how it is defined. Cross-session messaging exists in the same release, with @ mentions and SendMessage, and Anthropic's 2.1.222 entry says messages sent to other agent sessions through SendMessage are evaluated by the permission classifier before dispatch. That is a related surface, not the thesis.
Grantex answers the same question with an opposite default
Anthropic's fork mechanism inherits by default and then lets an operator narrow it back down with tools, disallowedTools, deny rules and worktree isolation. Somewhere else in the same broad space, an independently developed protocol takes the reverse position: authority does not travel down a delegation chain unless it is bounded on the way, by construction, at every hop. That protocol is Grantex, and this section verifies it directly rather than repeating what its own site says about itself.
Grantex is a single author project. Its GitHub repository, mishrasanjeev slash grantex, fetched directly this session, carries an Apache 2.0 license, 31 stars and 7 forks. The protocol specification inside it, SPEC.md, states its own header plainly: Version 1.0, Status Final, Last Updated February 2026, revision 3, and a following line reading Specification is now frozen. Changes require a new version. The repository's own changelog dates the initial protocol specification and auth service launch to 25 February 2026. Final here means frozen inside this one project's own versioning. Nothing in the specification claims IETF, W3C or any other standards body recognition, and this piece does not describe it as an industry standard.
A related document exists at the IETF. Independently phrased search passes agree on a title, Delegated Agent Authorization Protocol, DAAP, an author, S. Kumar of Grantex, the same person behind the GitHub repository, revision 00 published 27 February 2026, two days after Grantex's own changelog dates the initial version 1.0 launch, and revision 01 published 2 March 2026, both carrying intended status Informational. datatracker.ietf.org and ietf.org were blocked by this session's network egress policy on every attempt, so this record does not claim to have read the draft's own text directly, and grades what it describes as documented rather than verified for that reason. What matters more than the individual dates is the relationship between the two documents. This is one author's one architecture, described in a frozen specification and, days later, in an Internet Draft, not two independent proposals converging on the same idea. Treated as market signal, it is one data point, not two, and this piece treats it that way. It is also worth being precise about what an Internet Draft is and is not. It is an individual submission, available through IETF infrastructure because anyone can submit one. It is not an RFC. It is not adopted by the OAuth Working Group merely because its name uses an oauth prefix and it appears in that working group's own Datatracker listings. It is not IETF endorsement, certification or consensus, and nothing here should be read as claiming otherwise.
What actually attenuates, and what does not yet
Set the framing aside and read the mechanism, verified directly from SPEC.md fetched this session. When one agent spawns another, section 9 states the child's Grant Token must chain back to the original Principal's authorization, through three fields: parentAgt, naming the parent agent, parentGrnt, naming the parent grant, and delegationDepth, incremented by exactly 1 at each hop from a root grant at depth 0. That is a documented answer to the exact question Anthropic leaves undocumented for a Claude Code fork: where a subagent's authority came from is not left to be reconstructed from a permission prompt, it is a field on the token itself.
Three specific rules bound what a child grant can be, each quoted directly from the fetched specification text. Scope: sub agent scopes MUST be a subset of the parent's scopes, enforced at the delegation endpoint, which rejects with a 400 status if a requested scope is not present in the parent token's own scp claim. A subset relation permits equality, a child can hold exactly its parent's scopes, only a scope the parent lacks is prohibited, so this piece uses subset rather than strict subset, matching the specification's own enforced rule rather than a stronger phrase this session found used loosely elsewhere about the same project. Expiry: compute expiry as min(parent token exp, now + expiresIn), so a child's lifetime can be shorter than its parent's remaining validity and cannot be longer. Depth: implementations MUST enforce a developer configurable delegation depth limit, with a default RECOMMENDED limit of 3 and a hard cap of 10 the specification does not describe as configurable.
Revocation cascades by the same directness. Revoking a Grant MUST atomically revoke all descendant grants, grants whose parent_grant_id traces back to the revoked grant, at any depth, with implementations directed to use a recursive database query to mark the whole delegation tree revoked in one transaction. That is atomic marking of every descendant record at the moment a root is revoked, not a lookup a verifier performs later and not a separately maintained revocation tree structure, and it is the concrete version of a sentence this piece already asked in the abstract: revoking a parent should be able to take a child down with it.
That gap is not hypothetical inside Grantex's own shipped software. Its MCP authorization package, at version 2.0.2, the version this session independently confirmed as current against the npm registry, documents the limitation in its own README rather than leaving it to be discovered: middleware and introspection verify signatures and claims but do not perform a live revocation lookup, and a revoked but otherwise valid token can remain active until expiry. A companion file in the same repository, COMPATIBILITY.md, states plainly that local introspection and middleware do not check revocation and instructs integrators to treat this release as single process evaluation software until a corrected package is published. Cascade revocation exists as a real, atomic mechanism in the authorization service. Whether a specific integration actually consults it before letting an action proceed is a separate question, and for this one, currently shipping package, the documented answer is no.
The audit trail is real and specifically described, and this piece is deliberately narrow about what that specific description supports. Section 14, fetched directly, states audit logs MUST be append only at the API level, no update or delete endpoints, with each entry's hash incorporating the previous entry's hash. That is a genuine property: altering an entry without database level access breaks the chain from that point forward through anything that later reads it. This session found no description of that chain being anchored to any system outside Grantex's own database, so an operator with direct database access could in principle rewrite the full chain without an outside party detecting it from the chain alone. This piece uses append only and hash chained, the specification's own language, and not immutable or tamper proof, which the fetched text does not itself claim.
Two things worth naming precisely because they are easy to get wrong. Budget Allocation, a spending limit control this session found described in later Grantex material and search results describing the DAAP draft, is not part of the frozen version 1.0 specification, which this session searched directly and found no budget language in at all; treat it as a reference implementation and later draft feature layered on the frozen core, not something version 1.0 itself requires. And the project's own test count moves: an implementation report tied to the DAAP draft's original March period is reported elsewhere as roughly 362 tests, but the repository's own changelog, fetched directly this session, records a later entry, dated 8 April 2026, stating updated test stats, 3,536 tests across 28 packages. That later, larger figure is what this piece uses, not the earlier one, and no changelog entry visible to this session past that date restates a new total, so it is recorded as the most recent figure this session could verify, not as current to August 2026.
The Authority Provenance ledger
Moona Intelligence separates what a Grantex grant proves from what it does not, the same discipline this desk already applies to x401's proof requirements, rather than letting a well specified mechanism stand in for a fully proven chain of authority.
Authority grantor. The specification's own definitions are narrow and worth quoting directly: an Agent is an AI powered software process that takes autonomous actions on behalf of a Principal, and a Principal is the human user who authorizes an Agent to act on their behalf. A signed grant identifies that human Principal. Enterprise features this session found described, single sign on through OIDC, SAML and an LDAP preview, authenticate which human is signing in. They are not a separate, organization level Principal the specification itself defines, and this piece does not collapse a verified sign in into a broader organizational grantor.
Mandate or basis. Undocumented. A signed grant establishes that a specific human Principal authorized a specific Agent to hold a specific scope. Nothing this session found, in the specification, the README or the compliance material, establishes that the Principal actually held a corporate office, an account ownership right, a contractual authority or another organizational mandate entitling them to grant that scope in the first place. Identity of the grantor is documented. Legitimacy of the grant is not, and this piece records that as unknown rather than inferred from a successful sign in.
Delegated scope. Documented and specifically enforced: a subset check at the delegation endpoint, verified directly above. Whether a scope string like payments:initiate carries an enforceable numeric ceiling depends entirely on whether a receiving service parses and checks that string; nothing this session found makes such a convention a normatively enforced part of the protocol itself, and this piece does not treat a scope string as a guaranteed numeric policy.
Explicit limits. Documented precisely: expiry capped at min(parent exp, now + expiresIn), and delegation depth defaulting to 3 with a hard cap of 10. Budget controls, addressed above, sit outside the frozen core specification.
Inherited permissions and assumptions. A Grantex grant constrains the operation a receiving service actually checks it against, and nothing more. This piece found no description of Grantex discovering, constraining or revoking an ambient credential, an API key or a standing service account an agent might hold and use outside the Grantex path entirely. A service that never verifies a Grantex token is not bounded by anything this record found Grantex to enforce.
Revocation or modification. Cascade revocation is real and atomic inside the authorization service, verified directly above. Its effect at a specific receiving service depends on that service's own verification choice, online or offline, and on Grantex's own shipped MCP authorization package currently not checking revocation state at all. This piece does not describe cascade revocation as instantly and universally effective everywhere a Grantex token is accepted.
Challenge authority. Undocumented. This session found revoking a grant, and found no distinct mechanism for a Principal, an administrator or a third party to formally contest a grant's legitimacy separate from that binary act.
Recovery. Undocumented. Cascade revocation stops future use of a compromised chain. Nothing this session found addresses reversing, compensating for or rolling back an action a since revoked grant had already authorized before it was revoked.
Provenance evidence quality. Layered, not uniform, and worth stating plainly rather than rounding up. The mechanism that governs how much authority a child grant can hold, for how long, how many hops deep and how it gets cut off at the root is real, specific and independently verified against the specification's own text. Who was actually entitled to create the grant in the first place, whether a specific service verified it before acting, and whether anything survives to challenge or reverse an action already taken, are each undocumented or only partially enforced, and this piece keeps those apart rather than letting a well built attenuation mechanism imply a fully proven authority chain.
Why this belongs next to Anthropic's fork, not instead of it
These are not competing descriptions of the same system. Anthropic documents what Claude Code's own fork mechanism actually does: inherit broadly by default, then let an operator narrow it with explicit controls. Grantex documents a different system entirely, a protocol for a grant one agent hands to another across a service boundary, designed to attenuate by default and require an operator to do nothing extra for a child to end up with less than its parent, not more. Anthropic's design and Grantex's design are answers to the same underlying question, asked in two different runtime contexts, not two accounts of one mechanism. What Grantex demonstrates, independent of Anthropic and independent of Claude Code, is that full inheritance is a choice, not the only available default. A subagent could be built to receive strictly less than its parent by construction, with a signed record of exactly how much less and where the chain traces back to, and at least one real, if young and largely single author, project has built exactly that as its starting point rather than as an add on control.
A second draft reaches the IETF, aimed at WIMSE this time
Grantex is one author's protocol with an Internet Draft attached. Days after this piece last updated, a second, separate individual submission reached the IETF addressing the same Authority Inheritance question from a different angle: draft-asor-wimse-agent-delegation-chain-00, titled Verifiable Attenuated Delegation for AI Agent Chains, authored by Rafael Asor, whose listed affiliation is Attenu, the same organization behind attenu.io and its attenu-guard reference implementation. The draft's own header lists its category as Standards Track and its working group as WIMSE, Workload Identity in a Multi System Environment. That is the author's own stated intent, not a fact about the document's standing. This session found no evidence that the WIMSE working group has adopted it, no draft-ietf-wimse prefix, which the working group's own adopted documents carry, and nothing suggesting IETF consensus, RFC status or endorsement of any kind. It is an individual submission, reachable through the same IETF infrastructure any submitter can use, exactly as this piece already said about Grantex's own draft.
datatracker.ietf.org and every ietf.org host this session tried, including the mail archive, were blocked by this session's network egress policy on every attempt, the same blockage this piece already recorded against Grantex's draft in the prior update. That means this record cannot independently confirm the live Datatracker state directly: whether a revision past -00 has since appeared, the document's current IETF state such as Active Internet-Draft or Expired, or the exact page count an announcement email is reported to carry. What this session could and did verify directly is a full copy of the draft's own text, mirrored in attenu-guard's public GitHub repository as the specification source the reference implementation is built against, plus a repeated, independently phrased general web search that surfaced neighboring WIMSE and OAuth delegation drafts by name but never a revision -01 of this one, consistent with, though not proof of, a document posted the same day this session ran. The Datatracker page itself, and the announcement's page-count claim, are recorded here as manual-review, the same accepted state this desk already uses elsewhere in this piece, not as independently confirmed.
What the token has to carry
Read from that mirrored draft text directly. A Delegation Token is a JWS-signed JWT built on the OAuth 2.0 JWT access token profile, RFC 9068, carrying an authorization_details claim under RFC 9396's Rich Authorization Requests format: an array of typed authority objects, each naming permitted actions, target locations and a constraints object. Five constraint types are defined, a numeric ceiling that a child's value must not exceed, an enumerated set a child's value must belong to, a set a child's value must not belong to, a required string prefix and an ordered rank a child must not exceed, and the draft states a verifier encountering an unrecognized constraint type MUST deny, a fail-closed rule rather than a permissive default. Holder binding runs through a cnf claim and DPoP, RFC 9449, so a service checks the presenter proved control of the bound key on the request, not merely that it holds a copy of the token; mTLS-bound tokens are named as an alternative. Two depth claims bound the chain: del_depth, 0 at the root token and incremented by exactly 1 at each hop, and del_max_depth, set once on the root and required not to increase in any descendant.
The field doing the structurally new work is par_hash, required on every token after the root and required absent on the root itself. As read from the draft text, it is a base64url-encoded SHA-256 digest of the parent token's own JWS Signing Input, the exact bytes RFC 7515 section 5.1 defines as the base64url header joined to the base64url payload by a period, not a hash of the parent's claims alone and not a hash of its full compact serialization including its signature. The stated purpose is narrow and specific: stop a valid child token being presented next to a different or broader parent chain than the one it actually descends from, a failure mode the draft calls chain splicing. That is the claim this piece verifies and repeats. It is not a claim that par_hash defends against every form of token substitution attack, and nothing here should be read as saying so.
Offline verification, and what offline does not mean
The draft's verification procedure, as read directly, asks a final Enforcement Point holding trusted root keys to check, in order, denying on the first failure: every token's signature, with the root token verifying against the trusted root key; every non-root token's par_hash against its actual parent's Signing Input; the depth sequence, root at 0, each hop incrementing by 1, and the chain length staying under the root's del_max_depth; that every child's authority is subsumed by its immediate parent's, under the same five constraint rules described above, plus an expiry that is no later than the parent's; ordinary temporal validity on every token in the chain; a valid DPoP proof binding the presenter to the leaf token's cnf; revocation status against a cached Token Status List where one is referenced; and finally, only after every earlier check passes, whether the specific requested action falls inside the leaf token's own authority. That last step is the material finding this piece already anticipated in its framing above: delegation history is not an audit trail read after the fact, it is an input the enforcement point evaluates before authorizing the action itself.
The draft's own security considerations are explicit that this offline design has a cost, and this piece preserves that language rather than rounding it into a stronger guarantee. Because the status list is cached, an enforcement point can honor a token whose revocation has not yet propagated to its local cache; the draft frames this as a standard status-list trade-off between offline verification and revocation latency, to be bounded by shorter token lifetimes rather than eliminated. An online alternative exists too, an optional RFC 7009 revocation endpoint, which implies contacting an authorization server and trades away the offline property the rest of the design is built around. None of this describes instantaneous, guaranteed cascade revocation across every relying party; it describes a cacheable, offline-checkable status mechanism with a documented staleness window.
The parent is not consumed, and a narrower child is not proof of a legitimate root
Two limitations sit in the draft's own security considerations, not in a gap this piece is inferring, and both matter to Moona's broader Authority Lifecycle framing. First: attenuation creates a narrower child token, and the draft states this does not itself invalidate the broader parent token; a holder who still possesses the parent still possesses its broader authority until that parent separately expires or is revoked. This is delegation with retention, not a transfer that empties the source, and this piece is deliberate about that distinction because task language elsewhere in this space tends to blur it. Second, and this is a limitation the draft's text does not itself address rather than one it disputes: nothing in the token profile, the subsumption algorithm or the verification procedure establishes that the entity holding the root token, the Principal implied by iss and sub on DT0, was actually entitled under any organizational mandate to create the authority the root token represents. The chain proves internal lineage from a trusted root key forward. It does not reach backward into why that root key was trusted with that authority in the first place. That gap is the same one this piece already recorded against Grantex, restated against a different mechanism.
A related distinction the draft's own chain-splicing framing makes precise, and this piece keeps precise rather than widening: par_hash is a defense against a specific structural attack, presenting a genuine child beside the wrong parent, not a general claim about resisting every category of token theft, replay or substitution. The draft pairs it with short token lifetimes and holder binding as three separate, cooperating mitigations, not one mechanism doing all the work. Cryptographic proof that a chain narrowed correctly is also not proof that a downstream action the leaf token authorized actually completed as intended, and it is not a mechanism for reversing an action already taken before a delegation was revoked; the draft addresses neither, and this piece does not credit it with either.
Where this sits next to RFC 8693 and five neighboring drafts
The comparison this piece can state precisely, because the draft states it directly: RFC 8693, OAuth Token Exchange, already supports a nestable act claim recording prior actors in a chain, and the draft's own text describes that nested information as informational at the recipient rather than something the recipient is required to check hop by hop, with token exchange itself typically implying an authorization server round trip at each step. That is a narrower claim than saying RFC 8693 cannot represent delegation, which it plainly can and does. What this piece finds is not equivalently specified there is the combination the draft is proposing: offline verification, cryptographic parent-to-child linkage through par_hash, and a subsumption check the recipient enforces as a precondition of authorizing the action, rather than a chain it can choose to read or ignore.
The draft names, and states an intent to converge with, several neighboring individual submissions this session independently located and confirmed exist through search corroboration rather than direct fetch: draft-niyikiza-oauth-attenuating-agent-tokens, which the draft describes coordinating with specifically on the shared authorization_details type value to avoid two incompatible registrations; draft-coetzee-oauth-spt-txn-tokens, a differently shaped transaction-bound token design the draft says it intends to converge with rather than replace; draft-klrc-aiagent-auth, named as companion work; draft-reece-wimse-cross-org-delegation, a WIMSE problem-statement and requirements document the draft claims satisfies its stated requirement for an attenuation mechanism; and draft-mw-spice-actor-chain, a separate and more mature individual submission, five revisions deep as this session found it, that extends RFC 8693 itself with cryptographically committed actor-path profiles rather than replacing the token exchange model. That is at least six named individual efforts, including this one, working the same general problem from different angles, an active and unsettled area, not a gap one draft is filling alone. This piece does not repeat the newer draft's own framing of novelty without that context, and found no basis this session for a first-of-its-kind claim about any single one of them.
Attenu built the implementation before the draft had a number
attenu-guard's own GitHub changelog, fetched directly this session, dates a wire-format release, JWS Delegation Tokens plus a scenario harness, to 17 August 2026, ten days before the draft's own 27 August posting date, and records a 0.4.0 entry, renaming the project from delegation-guard to attenu-guard and adding Ed25519 verification, offline evidence verification and bundle redaction, dated 24 August 2026. A 0.4.1 entry, dated 26 August 2026, is a packaging fix, one day before the draft itself was posted. PyPI's own registry timestamps for both releases record 26 August 2026, a day later than the changelog's dates for 0.4.0, which this piece notes as a discrepancy between the project's internal release date and its public package distribution date rather than resolving it in either direction. Either dating places the reference implementation's core mechanism in existence before the Internet-Draft's own posting date, supporting this piece's reading that 27 August is the draft's publication event, not the first date this attenuation mechanism existed as running code.
What attenu-guard actually is, verified directly against its own repository, documentation and package registry entry: a permissively licensed Python library, one star and no forks on GitHub at the time this session checked, a size and adoption signal this piece states plainly rather than rounding into an established project. It exposes a local, in-process Guard API, issue, delegate, check, enforce, revoke, that computes a child's authority as the intersection of a parent's authority and a requested authority, and a separate wire format for delegation tokens intended for cross-service verification. Its own standards-alignment documentation, fetched directly this session, states plainly that the token profile itself, the JWT and JWS envelope, the RFC 9068 claims discipline, the RFC 9396 authorization_details format and the RFC 9449 holder binding, reuses existing IETF work, and names the draft's actual contribution as the cryptographically linked, subsumption-enforced, offline, multi-hop verification algorithm layered on top. Framework adapters exist, by this session's count, for thirteen agent frameworks including LangGraph, CrewAI, the OpenAI Agents SDK, Google's ADK and the Claude Agent SDK. Its own README states the library does not decide authority for you, a limitation this piece takes at face value: the library enforces a boundary a deployer configures, it does not itself establish that the deployer was entitled to configure that boundary in the first place, the same mandate gap already described above.
Maturity claims are represented as this session found them documented, not rounded up. The project's own README describes a self-authored property-based test harness generating four thousand random delegation trees per invariant and a seventeen-scenario adversarial red-team suite, both explicitly self-conducted by the maintainers, not an independent audit. This session found no independent security audit, no SOC 2 attestation and no third-party penetration test documented anywhere in the repository, its documentation site or its package registry entry. The README separately claims the library is enforced live on real applications built with Google ADK, CrewAI and LangGraph, a self-reported usage claim this piece records as such, distinct from independently verified or broad production adoption, which this session found no evidence of. A related project, attenu-derive, is described in the same repository family as a separate engine for computing a proposed authority set from application structure; this piece keeps it out of the Internet-Draft's own protocol scope, since the draft's token profile and verification procedure do not depend on it and this session found no place the draft itself names it as a required component.
Running this piece's own Authority Provenance discipline against the newer draft lands close to where it already landed for Grantex, for a different reason each time. Authority grantor: the root token's iss and sub identify a signing party and a Principal cryptographically, not an organizationally verified one. Mandate or basis: undocumented in the draft's own text; a verified chain says nothing about whether the root Principal held a corporate office, an account ownership right or another entitlement to grant the authority in the first place. Delegated scope and explicit limits: strong and specifically enforced, through the five-type constraint vocabulary, the expiry-monotonicity rule and the depth ceiling, each verified directly above. Inherited permissions: bounded by construction, a child cannot hold what its subsumption check would reject, which strengthens rather than replaces this piece's existing contrast between full inheritance and bounded, attenuating inheritance. Revocation: real through the status-list mechanism, bounded by the caching latency the draft itself documents, and explicitly not a claim that the broader parent authority disappears when a child is created. Challenge authority and recovery: this session found neither a formal contest mechanism separate from revocation nor any mechanism for reversing a downstream action a since-revoked token had already authorized; both remain outside the draft's stated scope. Evidence quality: high for the internal delegation lineage the chain itself proves, cryptographically and directly verifiable; low or unknown for root mandate legitimacy, ecosystem adoption at this stage, and for anything about the downstream effect an authorized action actually produced.
What the draft itself says about fan-out, injection and replay
Re-reading the mirrored draft text directly, two days after its own posting rather than treating the 27 August pass as final, surfaces language this record had summarized in substance but not yet quoted precisely. On fan-out, the draft's own words are direct: fan-out, one parent delegating to many children, is not limited by the token format and MUST be bounded by the issuing infrastructure if required. That is the draft naming its own boundary. The subsumption algorithm bounds what any one child can hold relative to its parent. It says nothing about how many children a parent may create, and the draft does not claim otherwise. A system can correctly enforce that child_1, child_2 and child_3 are each individually within their parent's scope while the aggregate authority those children exercise concurrently exceeds what anyone intended, and nothing in the token profile or the subsumption rule this record has already verified addresses that aggregate case. This record does not describe attenuation as a solution to fan-out or concurrent-authority budgeting, because the draft itself does not claim to be one.
On the confused-deputy and prompt-injection claim, the draft's own sentence is narrower than a casual reading of "cannot be induced to exercise authority the parent lacked" might suggest, and worth stating exactly: because each hop's authority is the meet, the intersection, of the parent's authority and the request, a child cannot be induced, for example by prompt injection, to exercise authority the parent lacked. Read precisely, that is a claim about authority escalation, not about misuse. It says an injected instruction cannot cause a child to hold or exercise more authority than its parent already granted it. It does not say, and this record does not attribute to the draft, that prompt injection cannot cause a child to misuse authority it already legitimately possesses inside that narrower grant, for example by directing an agent already authorized to send email toward an unintended recipient. This record keeps that distinction, escalation beyond the parent versus misuse within an existing grant, exactly where the draft's own sentence draws it.
On resource binding, the draft's own text states that tool audiences, carried in the token's aud and locations claims, are pinned, so a token minted for one resource cannot be replayed at another. That is a direct, verifiable claim about cross-resource replay, consistent with the locations field this record already found documented in the draft's authorization_details representation, now stated as its own explicit property rather than left implicit in the constraint vocabulary described above.
On revocation, reading the verification procedure's own normative language again confirms what this record already treated as conditional rather than mandatory, now stated more precisely: Delegation Tokens are RECOMMENDED, not REQUIRED, to be short-lived, and each token MAY, not MUST, carry a Token Status List reference. A verifier consults that reference where one is present. Carrying revocation-checkable state into a token at all is the base profile's own optional design, not a universal requirement every implementation of the draft is bound to satisfy.
Three more releases, and what their own test vectors do and do not cover
attenu-guard did not stand still in the two days after the draft's own posting. Its changelog, fetched directly again this session, records three further releases: 0.5.0 on 27 August, adding a Haystack adapter, adapters for two AutoGen successor frameworks, Microsoft Agent Framework and AG2, and supply-chain provenance tooling, SLSA build provenance through sigstore attestation and weekly OpenSSF Scorecard runs; 0.6.0 on 28 August, adding an Agent2Agent (A2A) adapter and, more relevant to this record's own verification discipline, packaging the library's interop test vectors inside the installed package itself as attenu_guard.vectors, accessible without cloning the repository; and 0.6.1 on 29 August, adding an eighth rejection vector for wildcard scope widening. PyPI's own registry confirms the same version and dates independently of the project's own changelog: 0.6.1 as the current release, uploaded 2026-08-29T03:57:25Z, with 0.5.0 and 0.6.0 uploaded on the two preceding days.
Fetching the repository's tests/vectors directory directly this session found nine files: one valid chain, valid_chain.json, and eight named rejection cases. Five map directly onto the subsumption dimensions this record already verified from the draft's own algorithm: reject_widened_scope.json, reject_exceeded_ceiling.json, reject_spliced_parent.json, reject_depth_exceeded.json and reject_nonmonotonic_exp.json. A sixth, reject_bad_signature.json, exercises signature forgery rather than a subsumption rule. Two more, reject_wildcard_boundary.json and reject_wildcard_widening.json, added 28 and 29 August, exercise a specific edge case in wildcard scope matching, that a broader wildcard scope like crm.* must not be treated as satisfying a check for a narrower concrete scope, and that a wildcard must not match past its own namespace boundary. That is real, specific adversarial coverage of exactly the properties it targets, and this record states it as such rather than rounding it down. It is equally precise about what the named set does not include: no vector in this directory exercises revocation, an already-revoked token being presented and correctly rejected, and none exercises token replay, a validly issued token being presented at a destination or in a context other than the one it was bound to. This record does not describe attenu-guard's shipped test coverage as reaching those two properties, because nothing this session found in the vectors directory does.
The repository's own signals of independent adoption are unchanged from the 27 August pass: 1 star, 0 forks, no additional contributor listed beyond the project's own maintainers when checked directly this session. A general search for independent implementations of the draft's wire profile, and a targeted search of the WIMSE working group's own mailing list archive for the draft by name, found neither an independent implementation nor any adoption discussion. This record continues to state working-group adoption as not established, and adds one concrete point of contrast rather than an inference: draft-ietf-wimse-arch, the WIMSE working group's own adopted architecture document, carries the draft-ietf- prefix the working group's own adopted documents use, the same marker this record already noted as absent from draft-asor-wimse-agent-delegation-chain. That prefix is what actual working-group adoption looks like in the Datatracker's own naming convention, and this draft does not carry it.
Verifying, separately, that the five neighboring drafts this record already named are not one organization's echo: draft-niyikiza-oauth-attenuating-agent-tokens is authored by N. Niyikiza of Tenuo; draft-coetzee-oauth-spt-txn-tokens by R. Coetzee of Violet Sky Security SEZC; draft-klrc-aiagent-auth by a multi-author group spanning Defakto Security, AWS, Zscaler, Ping Identity, OpenAI and Okta; and draft-reece-wimse-cross-org-delegation by Reece. Each is a genuinely separate author or organization from Attenu and from each other. That corroborates this record's existing treatment of them as distinct individual submissions working the same general problem, not as five citations of one company's proposal, while leaving unchanged the point this record has made throughout: an individual Internet-Draft, however many distinct authors are working adjacent ones, is a proposal circulating for comment, not evidence of market or standards convergence on its specific mechanism.
The question that is left
When the second agent attempts the action, the important question is not only what it can do. It is who authorized it to do that, and whether that authority actually survived the handoff.
Sources
This analysis interprets third-party reporting, research and announcements. Moona is not the original reporter of the underlying events.
