Repository navigation
[Feature] Delegated, attenuated grants for multi-agent delegation chains #129
Description
Summary
Allow a principal holding a grant to delegate a strictly narrower version of it to another principal (e.g., an orchestrator delegating to a sub-agent), producing a child token whose constraints are provably a subset of the parent's, with the full delegation chain recorded and revocable as a unit.
Why this matters
Multi-agent systems are the dominant emerging pattern (orchestrator → specialist sub-agents, A2A-style delegation), and "how do I scope what my sub-agent can do?" currently has no good answer at the tool-call layer. Monotonic attenuation is the classic strength of the capability model — supporting it makes the kernel's security model genuinely distinctive, and it composes directly with the federation work that already exists.
Proposed scope
Kernel.delegate(parent_token, child_principal, constraints=...) -> CapabilityToken:- child constraints must be equal-or-narrower on every axis (TTL ≤ parent remaining TTL, rows/fields ⊆ parent, scope ⊆ parent, same capability_id);
- any widening attempt raises a typed error with a stable reason.
- Token payload records
parent_token_idanddelegation_depth; configurablemax_delegation_depth(default small, e.g. 2). - Policy hook:
DefaultPolicyEnginemay deny delegation per capability/safety class (e.g., DESTRUCTIVE not delegable by default). - Revocation cascades: revoking a parent invalidates all descendants.
ActionTracefor a delegated invocation records the delegation chain (token ids only, no payloads).- Docs: a "delegation" section in
docs/capabilities.md+ runnable offline example with an orchestrator and a sub-agent principal.
Implementation notes
- Token model and HMAC signing:
src/weaver_kernel/tokens.py(CapabilityToken,HMACTokenProvider). Child tokens are signed normally; verification additionally walks parentage for revocation (requires revocation store lookups by token id — composes with the persistence work). - Constraint-narrowing comparison should reuse the grant-constraint logic already enforced on handle expansion (
handles.py,HandleConstraintViolation) rather than inventing a second subset checker. - Invariant I-06 (tokens bind principal + capability + constraints; no reuse across principals) is the heart of this feature: the child token is bound to the child principal — delegation mints a new binding, never shares the parent token.
- Policy placement: delegation checks in
policy.pymust run after sensitivity checks (rule-order trap in AGENTS.md). - Tests: narrowing enforced per axis; widening rejected (type + message asserted); cascade revocation; depth limit; delegated invocation produces a trace with the chain.
Acceptance criteria
-
delegate()mints child tokens that are verifiably narrower on every constraint axis. - Any widening attempt fails with a typed error and stable denial reason.
- Parent revocation invalidates all descendant tokens.
- Delegated invocations are traceable end-to-end via
kernel.explain()(chain of token ids). - Offline example + docs section added; CHANGELOG updated.
- No weakening of I-06; existing token tests still pass.
Out of scope
- Cross-kernel delegation (tokens remain kernel-scoped per the federation design; cross-kernel trust stays manifest-based).
- Capability composition (combining two capabilities into one grant).
- Macaroon-style offline attenuation without kernel involvement — worth a design note, not this issue.
References
- Capability-systems literature on attenuation (e.g., macaroons, object-capability model) as neutral background.
- Existing constraint enforcement: grant-constraint checks on handle expansion (v0.8.0, security: enforce grant constraints during handle expansion #76).
- Federation trust policies in
federation.pyfor the cross-kernel boundary this issue deliberately respects.
Priority: P1 · Effort: L · Impact: High
Activity
dgenio commentedon Jul 5, 2026
Filed an ADR evaluating whether delegated/attenuated grants should adopt an offline-attenuable token format (Biscuit, macaroon-style HMAC chaining) instead of today's shared-secret HMAC:
docs/adr/0001-token-signing-evolution.md(PR #247, tracking #224).Conclusion relevant to this issue: implement delegation via re-issuance (a delegation request is just
grant_capabilitywith narrowerconstraints) rather than offline attenuation, since this kernel's current deployment shape (single process, in-process registry) makes a same-process function call, not a network round-trip. Macaroon-style caveat chaining is documented as the future path if an offline-delegation requirement actually materializes (e.g. once #227's remote kernel mode ships) — #183'sconstraints["args"]vocabulary is deliberately shaped to be reusable as a caveat predicate language if that day comes. Biscuit is explicitly deferred (mandatory dependency, weakened default revocation posture, no current consumer).Generated by Claude Code
dgenio commentedon Aug 11, 2026
Closing as not planned under Gate 7 of
ROADMAP.md. Delegated/attenuated grants are technically attractive, but they require a larger token/revocation contract and should not precede exact-action binding (#258), lifecycle hardening (#259/#170), and real multi-agent adopter pull. Reopen when those prerequisites exist.