Authorization Chains
Multi-hop delegation chains allow an agent to act on behalf of another agent with verifiable, attenuated permissions.
Delegation Proof
Replaces the self-asserted provenance field with a cryptographically verifiable proof:
DelegationProof = { delegationToken: string, // existing format: payload.signature issuerPublicKey: string, // tulpa's public key (for recipient to verify) extensionSignature: string, // extension's sig over messageId + intent + JCS(payload) extensionPublicKey: string, // extension's key (from installation record) origin: ProvenanceOrigin, // now signed, not self-asserted}Recipient Verification
- Decode the delegation token, verify signature against
issuerPublicKey - Check
issuerPublicKeymatches the sender’s known public key - Verify
extensionSignatureagainstextensionPublicKeyfor this specific message - Check
extensionPublicKeymatches the key in the delegation token payload - Verify token hasn’t expired and permissions are sufficient
Multi-Hop Chains
For Extension A → Service B → Service C chains:
DelegationChain = { hops: DelegationHop[], // min 1, max 5}
DelegationHop = { delegator: string, // did:key of delegator delegatorPublicKey: string, delegate: string, // did:key or extension ID delegatePublicKey: string, permissions: Permission[], maxAutonomyTier: AutonomyTier, constraints: { intentTypes?: IntentType[], targetAgents?: string[], expiresAt: string, // ISO 8601 maxMessages?: number, }, signature: string, // delegator's sig over delegate + permissions + constraints}Chain Validation Rules
- Each hop’s permissions MUST be a subset of the previous hop’s (no privilege escalation)
- Each hop’s
maxAutonomyTierMUST be ≤ the previous hop’s tier - Each hop’s
expiresAtMUST be ≤ the previous hop’s expiration - Maximum chain depth: 5 hops
- The first hop MUST be signed by the tulpa owner’s key
Delegation Flow
A concrete example of a 3-hop chain: Owner → Extension → Sub-service → Recipient Agent.
Autonomy Tier Enforcement
| Origin | Required Tier | Recipient Can Verify? |
|---|---|---|
human | any | Yes — extension signature proves user input |
agent_approved | social or lower | Yes — delegation token tier checked |
agent_autonomous | transactional only | Yes — delegation token tier checked |
Revocation
- Each delegator maintains a revocation list
- The chain includes a
revocationEndpointper hop - Recipients can optionally check revocation endpoints (non-blocking, cached)
- Eventually consistent — TTL matches replay protection window (5 min)
Token Lifetime
Based on SPIFFE/UCAN research:
- Default TTL: 1–4 hours (not 48 hours)
- Extensions auto-renew before expiry
- 48-hour tokens require elevated review status
Prior Art
| Decision | Rationale | Prior Art |
|---|---|---|
| Flat hop array | Avoids exponential size growth | UCAN 1.0 CID-referenced proofs |
| Permission subset checking | Fits INK’s flat enum model | UCAN partial order |
| Separate delegation from invocation | Prevents confused deputy | UCAN delegation/invocation split |
| Short-lived tokens over revocation | Simpler in decentralized systems | SPIFFE SVIDs |
| Max 5 hops | 2–3 typical in practice | No protocol sets a hard limit |