> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.adid.dev/llms.txt.
> For full documentation content, see https://docs.adid.dev/llms-full.txt.

# Delegation Chains

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

```mermaid
graph LR
    H[Human DID<br />did:adi:human001] -->|"Delegation VC<br />scope: groceries, $200/wk<br />merchants: FreshMart, OrganicCo"| A[Agent DID<br />did:adi:agent:shop01]
    A -->|"Attenuated Delegation<br />scope: compare prices ONLY<br />(narrower than parent)"| SA[Sub-Agent DID<br />did:adi:agent:price01]

    style H fill:#dbeafe
    style A fill:#d1fae5
    style SA fill:#fef3c7
```

## 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 Level | Max Delegation Depth              |
| -------------- | --------------------------------- |
| Intern         | 0 (cannot delegate)               |
| Junior         | 0 (cannot delegate)               |
| Senior         | 1 (can delegate to one sub-agent) |
| Principal      | 3 (deep chains allowed)           |

## Delegation VC Schema

```json
{
  "@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

```mermaid
sequenceDiagram
    participant Human
    participant IDA API
    participant ADI Chain
    participant Agent

    Human->>IDA API: POST /delegations/issue
    Note right of Human: scope, constraints, agent DID
    IDA API->>ADI Chain: Verify human DID is active
    IDA API->>ADI Chain: Verify agent DID exists
    IDA API->>IDA API: Construct delegation VC
    IDA API->>IDA API: Sign with human's key
    IDA API->>ADI Chain: Register delegation on-chain
    IDA API->>Agent: Deliver delegation VC
    Agent->>Agent: Store delegation VC
    IDA API->>Human: Delegation confirmed
```

### Issue Delegation

```http
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)

```http
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

```http
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

```json
{
  "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 Scope           | Child Scope         | Valid? | Reason           |
| ---------------------- | ------------------- | ------ | ---------------- |
| `[shopping, prices]`   | `[prices]`          | Yes    | Subset of parent |
| `maxSpend: 200`        | `maxSpend: 100`     | Yes    | Stricter limit   |
| `merchants: [A, B, C]` | `merchants: [A, B]` | Yes    | Fewer merchants  |
| `expires: Sep`         | `expires: Jun`      | Yes    | Earlier expiry   |

### Invalid Attenuations

| Parent Scope        | Child Scope            | Valid? | Reason           |
| ------------------- | ---------------------- | ------ | ---------------- |
| `[prices]`          | `[prices, shopping]`   | No     | Added capability |
| `maxSpend: 200`     | `maxSpend: 500`        | No     | Higher limit     |
| `merchants: [A, B]` | `merchants: [A, B, C]` | No     | Added merchant   |
| `expires: Jun`      | `expires: Sep`         | No     | Later expiry     |

## Revocation

### Revoke a Delegation

```http
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

```http
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.