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

Activity

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