Skip to content

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

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions