Skip to navigation

Delegation Chains

View as Markdown

Delegation chains are the authorization framework for AI agents in IDA. They provide cryptographically verifiable proof that an agent is authorized to act on behalf of a human or organization, with precise scope limitations.

Delegation Model

Delegation VCscope: groceries, $200/wkmerchants: FreshMart, OrganicCo Attenuated Delegationscope: compare prices ONLY(narrower than parent) Human DIDdid:adi:human001 Agent DIDdid:adi:agent:shop01 Sub-Agent DIDdid:adi:agent:price01

Core Principles

1. Scope Attenuation

Each hop in a delegation chain can only narrow scope, never widen it.

This is enforced via Datalog policies in Biscuit tokens. If a human delegates “purchase groceries, max $200/week”, the agent:

  • CAN sub-delegate “compare grocery prices only” (narrower)
  • CANNOT sub-delegate “purchase electronics” (wider — different category)
  • CANNOT sub-delegate “purchase groceries, max $500/week” (wider — higher budget)

2. Chain Verification

Every delegation can be verified back to its root (a human or org DID). Verifiers check:

  1. Root delegator is a valid, active human/org DID
  2. Each hop’s delegation VC is signed by the delegator at that level
  3. Each hop’s scope is a subset of the parent scope
  4. No delegation VC in the chain is revoked or expired

3. Depth Limits

Delegation chains have configurable maximum depth to prevent unbounded sub-delegation:

Autonomy LevelMax Delegation Depth
Intern0 (cannot delegate)
Junior0 (cannot delegate)
Senior1 (can delegate to one sub-agent)
Principal3 (deep chains allowed)

Delegation VC Schema

{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://ida.infinia.io/ns/agent/v1"
],
"type": ["VerifiableCredential", "AgentDelegationCredential"],
"issuer": "did:adi:human001...",
"issuanceDate": "2026-03-15T09:00:00Z",
"expirationDate": "2026-09-15T00:00:00Z",
"credentialSubject": {
"id": "did:adi:agent:shop01...",
"delegator": "did:adi:human001...",
"delegate": "did:adi:agent:shop01...",
"scope": [
"purchase-groceries",
"compare-prices",
"manage-shopping-list"
],
"constraints": {
"maxSpendPerWeek": 200,
"currency": "USD",
"authorizedMerchants": ["FreshMart", "OrganicCo"],
"geographicRestriction": "US",
"timeWindow": {
"start": "08:00",
"end": "22:00",
"timezone": "America/New_York"
}
},
"attenuatedFrom": null,
"delegationDepth": 0,
"maxDepth": 1
},
"proof": { "..." }
}

Delegation Flow

Human to Agent

Issue Delegation

POST /api/v1/delegations/issue
Content-Type: application/json
Authorization: DIDAuth <human-signed-challenge>
{
"delegatorDid": "did:adi:human001...",
"delegateDid": "did:adi:agent:shop01...",
"scope": ["purchase-groceries", "compare-prices"],
"constraints": {
"maxSpendPerWeek": 200,
"currency": "USD",
"authorizedMerchants": ["FreshMart", "OrganicCo"]
},
"expirationDate": "2026-09-15T00:00:00Z",
"maxDepth": 1
}

Agent to Sub-Agent (Attenuated)

POST /api/v1/delegations/issue
Content-Type: application/json
Authorization: DIDAuth <agent-signed-challenge>
{
"delegatorDid": "did:adi:agent:shop01...",
"delegateDid": "did:adi:agent:price01...",
"scope": ["compare-prices"],
"constraints": {
"authorizedMerchants": ["FreshMart", "OrganicCo"],
"readOnly": true
},
"attenuatedFrom": "urn:uuid:parent-delegation-vc-id",
"expirationDate": "2026-06-15T00:00:00Z",
"maxDepth": 0
}

The API validates attenuation:

  • scope is a subset of parent’s scope
  • constraints are equal or stricter
  • expirationDate is not later than parent’s
  • maxDepth does not exceed parent’s remaining depth

Chain Verification

Verify a Delegation Chain

POST /api/v1/delegations/verify-chain
Content-Type: application/json
{
"agentDid": "did:adi:agent:price01...",
"requiredScope": "compare-prices",
"delegationChain": [
{ "credentialId": "urn:uuid:root-delegation" },
{ "credentialId": "urn:uuid:sub-delegation" }
]
}

Response

{
"valid": true,
"chain": [
{
"hop": 0,
"delegator": "did:adi:human001...",
"delegate": "did:adi:agent:shop01...",
"scope": ["purchase-groceries", "compare-prices"],
"valid": true
},
{
"hop": 1,
"delegator": "did:adi:agent:shop01...",
"delegate": "did:adi:agent:price01...",
"scope": ["compare-prices"],
"valid": true,
"attenuated": true
}
],
"rootDelegator": {
"did": "did:adi:human001...",
"type": "person",
"active": true
},
"effectiveScope": ["compare-prices"],
"effectiveConstraints": {
"authorizedMerchants": ["FreshMart", "OrganicCo"],
"readOnly": true
}
}

Scope Attenuation Examples

Valid Attenuations

Parent ScopeChild ScopeValid?Reason
[shopping, prices][prices]YesSubset of parent
maxSpend: 200maxSpend: 100YesStricter limit
merchants: [A, B, C]merchants: [A, B]YesFewer merchants
expires: Sepexpires: JunYesEarlier expiry

Invalid Attenuations

Parent ScopeChild ScopeValid?Reason
[prices][prices, shopping]NoAdded capability
maxSpend: 200maxSpend: 500NoHigher limit
merchants: [A, B]merchants: [A, B, C]NoAdded merchant
expires: Junexpires: SepNoLater expiry

Revocation

Revoke a Delegation

POST /api/v1/delegations/revoke
Authorization: DIDAuth <delegator-signed-challenge>
{
"delegationId": "urn:uuid:root-delegation",
"reason": "no_longer_needed"
}

When a delegation is revoked:

  1. The delegation VC is marked as revoked in the Revocation Registry
  2. All sub-delegations derived from it become invalid
  3. All active IBCTs based on this delegation are invalidated
  4. The agent (and sub-agents) can no longer present this chain

Narrowing an Active Delegation

POST /api/v1/delegations/narrow
Authorization: DIDAuth <delegator-signed-challenge>
{
"delegationId": "urn:uuid:root-delegation",
"newScope": ["compare-prices"],
"newConstraints": {
"maxSpendPerWeek": 100
}
}

This revokes the old delegation and issues a new, narrower one in a single atomic operation.