Skip to content

[Feature] Delegated, attenuated grants for multi-agent delegation chains #129

Closed as not planned

Description

@dgenio

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_id and delegation_depth; configurable max_delegation_depth (default small, e.g. 2).
  • Policy hook: DefaultPolicyEngine may deny delegation per capability/safety class (e.g., DESTRUCTIVE not delegable by default).
  • Revocation cascades: revoking a parent invalidates all descendants.
  • ActionTrace for 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.py must 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.py for the cross-kernel boundary this issue deliberately respects.

Priority: P1 · Effort: L · Impact: High

Activity

  1. dgenio commented on Jul 5, 2026

    @dgenio
    OwnerAuthor

    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_capability with narrower constraints) 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's constraints["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

  2. dgenio commented on Aug 11, 2026

    @dgenio
    OwnerAuthor

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions