# W3C Verifiable Credentials Delegation Guide

## Overview

The `@kya-os/mcp-i-core` package provides a production-ready implementation of W3C Verifiable Credentials for delegation in MCP-I systems. This guide explains how to issue, verify, and revoke delegation credentials.

## Table of Contents

1. [Quick Start](#quick-start)
2. [Architecture](#architecture)
3. [Issuing Delegation Credentials](#issuing-delegation-credentials)
4. [Verifying Delegations](#verifying-delegations)
5. [Revocation with StatusList2021](#revocation-with-statuslist2021)
6. [Cascading Revocation](#cascading-revocation)
7. [Tool Protection](#tool-protection)
8. [Best Practices](#best-practices)

## Quick Start

```typescript
import {
  createDelegationIssuer,
  createDelegationVerifier,
  createStatusListManager,
} from '@kya-os/mcp-i-core';

// 1. Create issuer
const issuer = createDelegationIssuer({
  identityProvider: {
    getDID: async () => 'did:key:z6Mk...',
    getKeyId: async () => 'did:key:z6Mk...#key-1',
    getPrivateKey: async () => privateKeyBase64,
  },
  signVC: async (vc) => {
    // Sign the VC using Ed25519Signature2020
    return signedVC;
  },
});

// 2. Issue delegation
const delegation = await issuer.issue({
  subjectDid: 'did:key:z6Mkp...',
  constraints: {
    scope: {
      allowedTools: ['read_file', 'write_file'],
      allowedResources: ['/documents/*'],
    },
    budget: {
      maxCost: 100,
      currency: 'USD',
    },
    time: {
      notBefore: new Date().toISOString(),
      notAfter: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
    },
  },
  audience: 'https://api.example.com',
});

// 3. Verify delegation
const verifier = createDelegationVerifier({
  resolveDID: async (did) => {
    // Resolve DID to DID Document
    return didDocument;
  },
  verifySignature: async (vc, publicKey) => {
    // Verify signature
    return true;
  },
});

const result = await verifier.verify(delegation);
console.log(result.valid); // true
```

## Architecture

The delegation system consists of several key components:

```
┌─────────────────────────────────────────────────────────────┐
│                    Delegation System                         │
├─────────────────────────────────────────────────────────────┤
│                                                               │
│  ┌───────────────────┐      ┌────────────────────┐         │
│  │ Delegation        │      │ Delegation         │         │
│  │ Issuer            │─────▶│ Credential (VC)    │         │
│  │ (Ed25519)         │      │ - Constraints      │         │
│  └───────────────────┘      │ - Proof            │         │
│                              │ - Status           │         │
│                              └────────────────────┘         │
│                                      │                       │
│                                      ▼                       │
│  ┌───────────────────┐      ┌────────────────────┐         │
│  │ Delegation        │◀─────│ StatusList2021     │         │
│  │ Verifier          │      │ Manager            │         │
│  │ (DID Resolution)  │      │ (Revocation)       │         │
│  └───────────────────┘      └────────────────────┘         │
│          │                           │                       │
│          ▼                           ▼                       │
│  ┌───────────────────┐      ┌────────────────────┐         │
│  │ Tool Protection   │      │ Cascading          │         │
│  │ Service           │      │ Revocation         │         │
│  │ (Access Control)  │      │ (Graph-based)      │         │
│  └───────────────────┘      └────────────────────┘         │
│                                                               │
└─────────────────────────────────────────────────────────────┘
```

### Core Components

1. **DelegationCredentialIssuer**: Creates W3C VC delegation credentials
2. **DelegationCredentialVerifier**: Verifies delegation credentials
3. **StatusList2021Manager**: Manages revocation lists efficiently
4. **DelegationGraphManager**: Tracks delegation chains
5. **CascadingRevocationManager**: Handles chain revocation
6. **ToolProtectionService**: Enforces delegation requirements

## Issuing Delegation Credentials

### Basic Issuance

```typescript
import { DelegationCredentialIssuer } from '@kya-os/mcp-i-core';

const issuer = new DelegationCredentialIssuer({
  identityProvider: {
    getDID: async () => 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK',
    getKeyId: async () => 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#key-1',
    getPrivateKey: async () => privateKeyBase64,
  },
  signVC: async (vc) => {
    // Implement Ed25519Signature2020 signing
    const signature = await ed25519.sign(canonicalJson, privateKey);
    return {
      ...vc,
      proof: {
        type: 'Ed25519Signature2020',
        created: new Date().toISOString(),
        verificationMethod: keyId,
        proofPurpose: 'assertionMethod',
        proofValue: `z${base58btc.encode(signature)}`,
      },
    };
  },
});
```

### CRISP Constraints

Delegation credentials use CRISP constraints (Cost, Resource, Identity, Scope, Purpose):

```typescript
const constraints: DelegationConstraints = {
  // Budget constraint (C - Cost)
  budget: {
    maxCost: 100,
    currency: 'USD',
    costPer: 'call', // or 'hour', 'day', 'month'
  },

  // Scope constraint (S - Scope)
  scope: {
    allowedTools: ['read_file', 'write_file', 'list_directory'],
    allowedResources: [
      '/documents/*',
      '/public/data/*.json',
    ],
    deniedTools: ['delete_all'], // Explicit denials
  },

  // Time constraint (implicit P - Purpose)
  time: {
    notBefore: '2025-10-17T00:00:00Z',
    notAfter: '2025-10-18T00:00:00Z',
    maxDuration: 3600, // seconds
  },
};

const delegation = await issuer.issue({
  subjectDid: 'did:key:z6Mkp...',
  constraints,
  audience: 'https://api.example.com',
});
```

### With Revocation Support

```typescript
// First, create a status list
const statusListManager = createStatusListManager({
  identityProvider,
  storage: new MemoryStatusListStorage(), // or your storage backend
  signVC,
});

const statusListId = await statusListManager.createStatusList('revocation');
const statusListUrl = `https://status.example.com/lists/${statusListId}`;

// Issue with revocation support
const delegation = await issuer.issue({
  subjectDid: 'did:key:z6Mkp...',
  constraints,
  audience: 'https://api.example.com',
  credentialStatus: {
    id: `${statusListUrl}#0`,
    type: 'StatusList2021Entry',
    statusPurpose: 'revocation',
    statusListIndex: '0',
    statusListCredential: statusListUrl,
  },
});
```

## Verifying Delegations

### Basic Verification

```typescript
import { DelegationCredentialVerifier } from '@kya-os/mcp-i-core';

const verifier = new DelegationCredentialVerifier({
  // DID resolution
  resolveDID: async (did: string) => {
    const response = await fetch(`https://did-resolver.example.com/${did}`);
    return await response.json();
  },

  // Signature verification
  verifySignature: async (vc: VerifiableCredential, publicKey: string) => {
    const proof = vc.proof as Ed25519Signature2020Proof;
    const payload = canonicalizeVC(vc);
    const signature = base58btc.decode(proof.proofValue.slice(1)); // Remove 'z'
    return await ed25519.verify(signature, payload, publicKey);
  },

  // Status list resolution (for revocation checks)
  resolveStatusList: async (url: string) => {
    const response = await fetch(url);
    return await response.json();
  },
});

const result = await verifier.verify(delegation);

if (result.valid) {
  console.log('✅ Delegation is valid');
  console.log('Subject:', delegation.credentialSubject.id);
  console.log('Allowed tools:', delegation.credentialSubject.delegation.constraints.scope.allowedTools);
} else {
  console.error('❌ Delegation is invalid');
  console.error('Errors:', result.errors);
}
```

### Verification Result

```typescript
interface DelegationVCVerificationResult {
  valid: boolean;
  checks: {
    structure: boolean;        // W3C VC structure valid
    signature: boolean;        // Cryptographic signature valid
    expiration: boolean;       // Not expired
    notBefore: boolean;        // Currently active
    revocation?: boolean;      // Not revoked (if status list present)
    didResolution: boolean;    // DID resolved successfully
  };
  errors: string[];            // List of errors if invalid
  warnings: string[];          // Non-fatal warnings
}
```

### Constraint Validation

```typescript
// Check if delegation allows specific tool
function canExecuteTool(delegation: DelegationCredential, toolName: string): boolean {
  const constraints = delegation.credentialSubject.delegation.constraints;

  // Check scope
  if (constraints.scope.allowedTools && !constraints.scope.allowedTools.includes(toolName)) {
    return false;
  }

  if (constraints.scope.deniedTools?.includes(toolName)) {
    return false;
  }

  return true;
}

// Check budget remaining
function checkBudget(delegation: DelegationCredential, usedCost: number): boolean {
  const budget = delegation.credentialSubject.delegation.constraints.budget;
  if (!budget) return true;

  return usedCost < budget.maxCost;
}
```

## Revocation with StatusList2021

StatusList2021 provides efficient, privacy-preserving credential revocation using compressed bitstrings.

### Creating Status Lists

```typescript
import { StatusList2021Manager } from '@kya-os/mcp-i-core';

const manager = createStatusListManager({
  identityProvider,
  storage, // Implement StatusListStorageProvider
  signVC,
});

// Create revocation list
const revocationListId = await manager.createStatusList('revocation');

// Create suspension list (optional)
const suspensionListId = await manager.createStatusList('suspension');
```

### Revoking Credentials

```typescript
// Revoke a specific credential by its status list index
await manager.setStatus(revocationListId, 42, true); // Index 42 is now revoked

// Check status
const isRevoked = await manager.getStatus(revocationListId, 42);
console.log('Revoked:', isRevoked); // true

// Un-revoke (rare, but possible)
await manager.setStatus(revocationListId, 42, false);
```

### Bulk Operations

```typescript
// Revoke multiple credentials efficiently
const indicesToRevoke = [0, 5, 10, 42, 100, 1000];

for (const index of indicesToRevoke) {
  await manager.setStatus(revocationListId, index, true);
}

// The bitstring is automatically compressed (gzip + base64)
// Very efficient: 131,072 credentials = ~16KB compressed
```

### Status List Credentials

The status list itself is a W3C Verifiable Credential:

```json
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://w3id.org/vc/status-list/2021/v1"
  ],
  "id": "https://status.example.com/lists/revocation-123",
  "type": ["VerifiableCredential", "StatusList2021Credential"],
  "issuer": "did:key:z6Mk...",
  "issuanceDate": "2025-10-17T00:00:00Z",
  "credentialSubject": {
    "id": "https://status.example.com/lists/revocation-123#list",
    "type": "StatusList2021",
    "statusPurpose": "revocation",
    "encodedList": "H4sIAAAAAAAAA-3BMQEAAADCoPVP..."
  },
  "proof": { ... }
}
```

## Cascading Revocation

When a delegation is revoked, all sub-delegations should also be revoked.

### Setting Up Delegation Graph

```typescript
import {
  DelegationGraphManager,
  CascadingRevocationManager
} from '@kya-os/mcp-i-core';

// Create delegation graph
const graph = createDelegationGraph({
  storage: new MemoryDelegationGraphStorage(), // or your storage
});

// Track delegations
await graph.addDelegation({
  id: 'delegation-root',
  issuerDid: 'did:key:issuer',
  subjectDid: 'did:key:delegate1',
  parentId: null,
  issuedAt: new Date().toISOString(),
  expiresAt: new Date(Date.now() + 86400000).toISOString(),
  statusListUrl: 'https://status.example.com/lists/123',
  statusListIndex: 0,
});

await graph.addDelegation({
  id: 'delegation-sub',
  issuerDid: 'did:key:delegate1',
  subjectDid: 'did:key:delegate2',
  parentId: 'delegation-root', // Link to parent
  issuedAt: new Date().toISOString(),
  expiresAt: new Date(Date.now() + 43200000).toISOString(),
  statusListUrl: 'https://status.example.com/lists/123',
  statusListIndex: 1,
});
```

### Cascading Revocation

```typescript
const cascadingRevocation = createCascadingRevocationManager({
  delegationGraph: graph,
  statusListManager: manager,
  issuerIdentity: identityProvider,
  signVC,
});

// Revoke with cascade
const revokedIds = await cascadingRevocation.revoke('delegation-root', {
  cascade: true,
  reason: 'Security incident',
});

console.log('Revoked delegations:', revokedIds);
// ['delegation-root', 'delegation-sub']
```

### Revocation Hooks

```typescript
// Register hook for custom logic
cascadingRevocation.onRevoke(async (event) => {
  console.log('Revoked:', event.credentialId);
  console.log('Reason:', event.reason);
  console.log('Cascade:', event.cascade);

  // Send notification
  await notifyUser(event.credentialId, event.reason);

  // Log to audit trail
  await auditLog.record({
    action: 'delegation.revoke',
    credentialId: event.credentialId,
    timestamp: new Date(),
  });
});
```

## Tool Protection

Enforce delegation requirements on sensitive tools:

```typescript
import {
  ToolProtectionService,
  InMemoryToolProtectionCache
} from '@kya-os/mcp-i-core';

const toolProtection = new ToolProtectionService({
  cache: new InMemoryToolProtectionCache(),
  delegationVerifier: verifier,
});

// Configure protection
await toolProtection.setProtection('delete_database', {
  requiresDelegation: true,
  requiredScopes: ['admin', 'delete'],
  budgetLimit: 1000,
  rateLimit: {
    maxCalls: 10,
    windowSeconds: 3600,
  },
});

// Check access
try {
  const hasAccess = await toolProtection.checkAccess(
    'delete_database',
    'did:key:z6Mkp...',
    delegation
  );

  if (hasAccess) {
    // Execute tool
    await deleteDatabase();

    // Track usage
    await toolProtection.trackUsage('delete_database', 'did:key:z6Mkp...', {
      cost: 100,
      timestamp: Date.now(),
    });
  }
} catch (error) {
  console.error('Access denied:', error.message);
}
```

## Best Practices

### 1. Key Management

```typescript
// ✅ DO: Use secure key storage
import { SecureKeyStore } from './secure-storage';

const identityProvider = {
  getDID: async () => await keyStore.getDID(),
  getPrivateKey: async () => await keyStore.getPrivateKey(),
};

// ❌ DON'T: Hardcode private keys
const identityProvider = {
  getDID: async () => 'did:key:z6Mk...',
  getPrivateKey: async () => 'my-private-key-123', // NEVER DO THIS
};
```

### 2. Principle of Least Privilege

```typescript
// ✅ DO: Minimal scope
const constraints = {
  scope: {
    allowedTools: ['read_public_data'], // Only what's needed
    allowedResources: ['/public/*.json'], // Specific paths
  },
  time: {
    notBefore: now,
    notAfter: now + 3600000, // 1 hour only
  },
};

// ❌ DON'T: Over-permission
const constraints = {
  scope: {
    allowedTools: ['*'], // Too broad
  },
  time: {
    notAfter: now + 31536000000, // 1 year is too long
  },
};
```

### 3. Always Enable Revocation

```typescript
// ✅ DO: Include revocation support
const delegation = await issuer.issue({
  subjectDid,
  constraints,
  credentialStatus: statusEntry, // Always include this
});

// ❌ DON'T: Skip revocation
const delegation = await issuer.issue({
  subjectDid,
  constraints,
  // No credentialStatus = can't revoke!
});
```

### 4. Verify Before Use

```typescript
// ✅ DO: Always verify
async function executeTool(toolName: string, delegation: DelegationCredential) {
  const result = await verifier.verify(delegation);
  if (!result.valid) {
    throw new Error(`Invalid delegation: ${result.errors.join(', ')}`);
  }

  // Now execute tool
  return await tools[toolName]();
}

// ❌ DON'T: Trust without verification
async function executeTool(toolName: string, delegation: DelegationCredential) {
  // Skipping verification = security vulnerability
  return await tools[toolName]();
}
```

### 5. Monitor Usage

```typescript
// ✅ DO: Track and alert
toolProtection.onUsage(async (event) => {
  await metrics.record({
    tool: event.toolName,
    user: event.userDid,
    cost: event.cost,
    timestamp: event.timestamp,
  });

  // Alert on suspicious patterns
  if (event.cost > 1000) {
    await alerting.send(`High cost usage: ${event.cost}`);
  }
});
```

## Complete Example

```typescript
import {
  createDelegationIssuer,
  createDelegationVerifier,
  createStatusListManager,
  createCascadingRevocationManager,
  createDelegationGraph,
  ToolProtectionService,
  InMemoryToolProtectionCache,
  MemoryStatusListStorage,
  MemoryDelegationGraphStorage,
} from '@kya-os/mcp-i-core';

// Setup
const issuer = createDelegationIssuer({ identityProvider, signVC });
const verifier = createDelegationVerifier({ resolveDID, verifySignature, resolveStatusList });
const statusListManager = createStatusListManager({ identityProvider, storage: new MemoryStatusListStorage(), signVC });
const delegationGraph = createDelegationGraph({ storage: new MemoryDelegationGraphStorage() });
const cascadingRevocation = createCascadingRevocationManager({
  delegationGraph,
  statusListManager,
  issuerIdentity: identityProvider,
  signVC,
});
const toolProtection = new ToolProtectionService({
  cache: new InMemoryToolProtectionCache(),
  delegationVerifier: verifier,
});

// 1. Issue delegation
const statusListId = await statusListManager.createStatusList('revocation');
const delegation = await issuer.issue({
  subjectDid: 'did:key:delegate',
  constraints: {
    scope: { allowedTools: ['read', 'write'] },
    budget: { maxCost: 100, currency: 'USD' },
    time: {
      notBefore: new Date().toISOString(),
      notAfter: new Date(Date.now() + 3600000).toISOString(),
    },
  },
  audience: 'https://api.example.com',
  credentialStatus: {
    id: `https://status.example.com/lists/${statusListId}#0`,
    type: 'StatusList2021Entry',
    statusPurpose: 'revocation',
    statusListIndex: '0',
    statusListCredential: `https://status.example.com/lists/${statusListId}`,
  },
});

// 2. Track in graph
await delegationGraph.addDelegation({
  id: delegation.id!,
  issuerDid: await identityProvider.getDID(),
  subjectDid: 'did:key:delegate',
  parentId: null,
  issuedAt: delegation.issuanceDate,
  expiresAt: delegation.expirationDate!,
  statusListUrl: `https://status.example.com/lists/${statusListId}`,
  statusListIndex: 0,
});

// 3. Configure tool protection
await toolProtection.setProtection('write', {
  requiresDelegation: true,
  requiredScopes: ['write'],
  budgetLimit: 50,
});

// 4. Execute tool with delegation
const result = await verifier.verify(delegation);
if (result.valid) {
  const hasAccess = await toolProtection.checkAccess('write', 'did:key:delegate', delegation);
  if (hasAccess) {
    // Execute tool
    await executeWriteTool();

    // Track usage
    await toolProtection.trackUsage('write', 'did:key:delegate', {
      cost: 10,
      timestamp: Date.now(),
    });
  }
}

// 5. Revoke if needed
await cascadingRevocation.revoke(delegation.id!, {
  cascade: true,
  reason: 'Project completed',
});
```

## Next Steps

- [StatusList2021 Guide](./STATUSLIST2021_GUIDE.md) - Deep dive into revocation
- [Compliance Matrix](./COMPLIANCE_MATRIX.md) - Schema compliance status
- [API Reference](./API_REFERENCE.md) - Complete API documentation
