|
| 1 | +--- |
| 2 | +title: Delegation Chains |
| 3 | +description: How authority envelopes enable scoped, verifiable delegation between agents |
| 4 | +--- |
| 5 | + |
| 6 | +# Delegation Chains |
| 7 | + |
| 8 | +In multi-agent workflows, one agent often needs to act on behalf of another. Authority Envelopes provide a cryptographic mechanism for scoped, verifiable delegation. |
| 9 | + |
| 10 | +--- |
| 11 | + |
| 12 | +## The Problem |
| 13 | + |
| 14 | +Consider a workflow where Agent A asks Agent B to perform a database query, and Agent B delegates that to Agent C (a specialized database reader). Without delegation: |
| 15 | + |
| 16 | +- Agent C has no proof that Agent A authorized this action |
| 17 | +- There's no way to scope what Agent C is allowed to do |
| 18 | +- The chain of authority is invisible to enforcement points |
| 19 | + |
| 20 | +Trust badges prove **identity** ("I am Agent B"), but not **authority** ("Agent A authorized me to read from the database"). |
| 21 | + |
| 22 | +--- |
| 23 | + |
| 24 | +## Authority Envelopes |
| 25 | + |
| 26 | +An **Authority Envelope** is a JWS-signed token (defined in [RFC-008](https://github.com/capiscio/capiscio-rfcs/blob/main/docs/008-delegated-authority-envelopes.md)) that grants scoped authority from one agent to another. |
| 27 | + |
| 28 | +Key claims in an envelope: |
| 29 | + |
| 30 | +| Claim | Description | |
| 31 | +|-------|-------------| |
| 32 | +| `iss` | DID of the agent granting authority | |
| 33 | +| `sub` | DID of the agent receiving authority | |
| 34 | +| `cap` | Capability class (e.g., `tools.database.read`) | |
| 35 | +| `depth` | Remaining delegation depth (decrements at each hop) | |
| 36 | +| `exp` | Expiration time | |
| 37 | +| `parent_hash` | SHA-256 hash of the parent envelope (for chain integrity) | |
| 38 | +| `constraints` | Optional restrictions (time windows, resource filters) | |
| 39 | +| `enforcement_mode_min` | Minimum enforcement mode for this delegation | |
| 40 | + |
| 41 | +--- |
| 42 | + |
| 43 | +## Chain Structure |
| 44 | + |
| 45 | +Envelopes form **hash-linked chains** where each child references its parent: |
| 46 | + |
| 47 | +``` |
| 48 | +┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ |
| 49 | +│ Root Envelope │────▶│ Child Envelope │────▶│ Leaf Envelope │ |
| 50 | +│ │ │ │ │ │ |
| 51 | +│ iss: Agent A │ │ iss: Agent B │ │ iss: Agent C │ |
| 52 | +│ sub: Agent B │ │ sub: Agent C │ │ sub: Agent D │ |
| 53 | +│ cap: tools.* │ │ cap: tools.db.* │ │ cap: tools.db.rd │ |
| 54 | +│ depth: 2 │ │ depth: 1 │ │ depth: 0 │ |
| 55 | +└──────────────────┘ └──────────────────┘ └──────────────────┘ |
| 56 | +``` |
| 57 | + |
| 58 | +### Monotonic Narrowing |
| 59 | + |
| 60 | +Each link in the chain must be **equal or narrower** than its parent: |
| 61 | + |
| 62 | +- **Capability class** can only narrow (e.g., `tools.*` → `tools.db.*` → `tools.db.read`) |
| 63 | +- **Delegation depth** must decrease |
| 64 | +- **Constraints** can only become more restrictive |
| 65 | +- **Expiration** cannot exceed the parent's expiration |
| 66 | + |
| 67 | +This ensures authority can never be escalated through delegation. |
| 68 | + |
| 69 | +### Enforcement Mode Escalation |
| 70 | + |
| 71 | +Envelopes can set a minimum enforcement mode via `enforcement_mode_min`. This mode can only **escalate** (become stricter) through the chain: |
| 72 | + |
| 73 | +| Mode | Strictness | Behavior on DENY | |
| 74 | +|------|-----------|-------------------| |
| 75 | +| `EM-OBSERVE` | Lowest | Logged, request proceeds | |
| 76 | +| `EM-GUARD` | Medium | Request blocked | |
| 77 | +| `EM-STRICT` | Highest | Request blocked, unknown obligations denied | |
| 78 | + |
| 79 | +If a parent sets `EM-GUARD`, no child can relax it to `EM-OBSERVE`. |
| 80 | + |
| 81 | +--- |
| 82 | + |
| 83 | +## Chain Verification |
| 84 | + |
| 85 | +When the gateway PEP receives a request with delegation headers, it verifies the entire chain (RFC-008 §9.2): |
| 86 | + |
| 87 | +1. **Signature verification** — Each envelope is signed by its issuer |
| 88 | +2. **Hash chain integrity** — Each child's `parent_hash` matches the parent |
| 89 | +3. **Narrowing validation** — Capabilities, depth, and constraints narrow monotonically |
| 90 | +4. **Badge binding** — The leaf envelope's `sub` matches the caller's badge subject |
| 91 | +5. **Depth limits** — Chain length does not exceed `MaxChainDepth` (default: 10) |
| 92 | +6. **Expiration** — All envelopes in the chain are within their validity period |
| 93 | +7. **Enforcement mode** — The strictest mode across the chain is applied |
| 94 | + |
| 95 | +--- |
| 96 | + |
| 97 | +## Trust Boundaries |
| 98 | + |
| 99 | +Delegation chains can span organizational boundaries. The `OrgTrustBoundary` configuration controls whether cross-org chains are accepted: |
| 100 | + |
| 101 | +- **Same-org chains**: All issuers share the same org DID prefix — always accepted |
| 102 | +- **Cross-org chains**: Issuers from different orgs — accepted only when `OrgTrustBoundary` is empty or matches |
| 103 | + |
| 104 | +--- |
| 105 | + |
| 106 | +## Relationship to Badges |
| 107 | + |
| 108 | +Envelopes and badges serve complementary roles: |
| 109 | + |
| 110 | +| | Badge | Envelope | |
| 111 | +|-|-------|----------| |
| 112 | +| **Proves** | Identity ("I am Agent B") | Authority ("Agent A authorized me") | |
| 113 | +| **Issued by** | CA / Self-signed | Another agent | |
| 114 | +| **Scope** | Agent-level trust | Per-action capability | |
| 115 | +| **Lifetime** | Hours to days | Minutes to hours | |
| 116 | +| **Header** | `X-Capiscio-Badge` | `X-Capiscio-Authority` | |
| 117 | + |
| 118 | +A delegated request carries both: the badge proves who the caller is, and the envelope chain proves they have authority to act. |
| 119 | + |
| 120 | +--- |
| 121 | + |
| 122 | +## Transport Headers |
| 123 | + |
| 124 | +Delegation chains are transmitted via HTTP headers: |
| 125 | + |
| 126 | +| Header | Content | |
| 127 | +|--------|---------| |
| 128 | +| `X-Capiscio-Authority` | Leaf envelope JWS | |
| 129 | +| `X-Capiscio-Authority-Chain` | Base64url-encoded JSON array of the full chain | |
| 130 | +| `X-Capiscio-Badge-Map` | JSON object mapping intermediate agent DIDs to their badge JWS tokens | |
| 131 | + |
| 132 | +--- |
| 133 | + |
| 134 | +## DID Resolution |
| 135 | + |
| 136 | +Chain verification requires resolving issuer DIDs to their public keys. CapiscIO uses a **composite key resolver** that handles both DID methods: |
| 137 | + |
| 138 | +| DID Method | Resolution | Example | |
| 139 | +|------------|-----------|---------| |
| 140 | +| `did:key` | Local decode (no network) | `did:key:z6Mk...` | |
| 141 | +| `did:web` | HTTPS fetch of DID document | `did:web:agent.example.com` | |
| 142 | + |
| 143 | +### DID:web Security |
| 144 | + |
| 145 | +The `did:web` resolver includes SSRF protections (RFC-008 §17.1): |
| 146 | + |
| 147 | +- **HTTPS required** in production (HTTP only allowed in dev mode) |
| 148 | +- **Blocked destinations**: localhost, private IPs (10.x, 172.16.x, 192.168.x), link-local, cloud metadata endpoints |
| 149 | +- **No redirect following** (prevents SSRF via redirect chains) |
| 150 | +- **Response size limits**: 64 KB maximum |
| 151 | +- **Request timeouts**: 10 seconds |
| 152 | +- **Document caching**: 5-minute TTL (reduces network calls) |
| 153 | + |
| 154 | +--- |
| 155 | + |
| 156 | +## Next Steps |
| 157 | + |
| 158 | +- [Create and use delegation chains](../how-to/security/delegation-chains.md) — Step-by-step guide |
| 159 | +- [Gateway setup](../how-to/security/gateway-setup.md) — Configure the PEP to verify chains |
| 160 | +- [Policy enforcement config](../reference/server/policy-enforcement.md) — Chain verification settings |
| 161 | +- [RFC-008](https://github.com/capiscio/capiscio-rfcs/blob/main/docs/008-delegated-authority-envelopes.md) — Full specification |
0 commit comments