# StatusList2021 Revocation Guide

## Overview

StatusList2021 is a W3C standard for efficient, privacy-preserving credential revocation. It uses bitstring compression to enable scalable revocation checking with minimal bandwidth and storage requirements.

**Key Benefits:**
- **Efficient**: 131,072 credentials in ~16KB compressed bitstring
- **Privacy-Preserving**: Correlates less than individual revocation lists
- **Scalable**: Single HTTP request to check any credential status
- **Batch Updates**: Update multiple credential statuses atomically

## How It Works

### Bitstring Compression

StatusList2021 uses a compressed bitstring where each credential gets assigned an index:

```
Bit Position:  0  1  2  3  4  5  6  7  ...  131071
Status:        0  1  0  0  1  0  0  0  ...  1
               ↑  ↑  ↑  ↑  ↑
               OK REV OK OK REV
```

- **0** = Credential is valid
- **1** = Credential is revoked

The bitstring is GZIP-compressed and encoded as base64, reducing ~16KB uncompressed to ~2-4KB compressed.

### Performance Characteristics

| Credential Count | Uncompressed Size | Compressed Size | HTTP Transfer |
|-----------------|-------------------|-----------------|---------------|
| 10,000          | ~1.2 KB           | ~400 bytes      | <1ms          |
| 100,000         | ~12 KB            | ~2 KB           | ~5ms          |
| 131,072 (max)   | ~16 KB            | ~4 KB           | ~10ms         |

**Comparison to Individual Revocation Lists:**
- Individual lists: N credentials = N HTTP requests
- StatusList2021: N credentials = 1 HTTP request

## Architecture

```
┌─────────────────────────────────────────────────────────────┐
│                    Issuer System                             │
├─────────────────────────────────────────────────────────────┤
│                                                               │
│  ┌──────────────┐         ┌─────────────────┐               │
│  │ Delegation   │────────▶│ StatusList2021  │               │
│  │ Credential   │         │ Manager         │               │
│  └──────────────┘         └─────────────────┘               │
│         │                          │                         │
│         │                          ▼                         │
│         │                  ┌──────────────┐                  │
│         │                  │ Bitstring    │                  │
│         │                  │ Storage      │                  │
│         │                  │ (Redis/DB)   │                  │
│         │                  └──────────────┘                  │
│         │                          │                         │
│         │                          ▼                         │
│         │                  ┌──────────────┐                  │
│         │                  │ Status List  │                  │
│         │                  │ VC Document  │                  │
│         │                  └──────────────┘                  │
│         │                          │                         │
│         └──────────────────────────┼─────────────────────────┘
│                                    │
│                                    ▼
│                            [Public HTTPS URL]
│                      https://issuer.com/status/1
│                                    │
├────────────────────────────────────┼─────────────────────────┐
│                                    │                          │
│              Verifier System       │                          │
│                                    ▼                          │
│                         ┌──────────────────┐                 │
│                         │ StatusList2021   │                 │
│                         │ Verifier         │                 │
│                         └──────────────────┘                 │
│                                    │                          │
│                                    ▼                          │
│                            [Check Status]                     │
│                         Valid ✓ or Revoked ✗                 │
└───────────────────────────────────────────────────────────────┘
```

## Basic Usage

### 1. Creating a Status List

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

// Initialize manager
const statusListManager = new StatusList2021Manager({
  issuerDid: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK',
  statusListUrl: 'https://issuer.example.com/status/1',
  storage: myStorageProvider, // Redis, DynamoDB, etc.
});

// Create a new status list
const statusListVC = await statusListManager.createStatusList({
  id: 'https://issuer.example.com/status/1',
  purpose: 'revocation',
});

console.log(statusListVC);
```

**Output:**
```json
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://w3id.org/vc/status-list/2021/v1"
  ],
  "id": "https://issuer.example.com/status/1",
  "type": ["VerifiableCredential", "StatusList2021Credential"],
  "issuer": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK",
  "issuanceDate": "2025-10-17T12:00:00Z",
  "credentialSubject": {
    "id": "https://issuer.example.com/status/1#list",
    "type": "StatusList2021",
    "statusPurpose": "revocation",
    "encodedList": "H4sIAAAAAAAAA+3BMQEAAADCoPVPbQwfoAAAAAAAAAAAAAAAAAAAAIC3AYbSVKsAQAAA"
  },
  "proof": {
    "type": "Ed25519Signature2020",
    "created": "2025-10-17T12:00:00Z",
    "verificationMethod": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK",
    "proofPurpose": "assertionMethod",
    "proofValue": "z58DAdFfa9SkqZMVPxAQpic7ndSayn1PzZs6ZjWp1CktyGesjuTSwRdoWhAfGFCF5bppETSTojQCrfFPP2oumHKtz"
  }
}
```

### 2. Issuing Credentials with Status

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

const issuer = new DelegationIssuer({
  issuerDid: 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK',
  privateKeyJwk: issuerPrivateKey,
});

// Allocate a status list index for this credential
const statusListIndex = await statusListManager.allocateIndex();

const delegation = await issuer.issue({
  subjectDid: 'did:key:z6MkrWXJPkxPCuQF7RqeKZFdZqBXz3oCG7PUty5dXLKGzELj',
  constraints: {
    scope: {
      allowedTools: ['read_file', 'list_directory'],
      allowedResources: ['/documents/*'],
    },
    time: {
      notBefore: new Date().toISOString(),
      notAfter: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
    },
  },
  credentialStatus: {
    id: `https://issuer.example.com/status/1#${statusListIndex}`,
    type: 'StatusList2021Entry',
    statusPurpose: 'revocation',
    statusListIndex: statusListIndex.toString(),
    statusListCredential: 'https://issuer.example.com/status/1',
  },
});

console.log('Issued delegation with status index:', statusListIndex);
```

### 3. Revoking a Credential

```typescript
// Revoke a credential by its status list index
await statusListManager.revokeCredential(statusListIndex);

console.log(`Credential at index ${statusListIndex} has been revoked`);

// The status list VC is automatically updated and republished
```

### 4. Checking Credential Status

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

const result = await verifyDelegation({
  credential: delegation,
  expectedAudience: 'https://api.example.com',
  checkStatus: true, // Enable status checking
});

if (!result.verified) {
  console.error('Verification failed:', result.error);
  if (result.statusRevoked) {
    console.error('Credential has been revoked!');
  }
}
```

## Integration with Delegation Credentials

### Credential Structure

When a delegation credential includes status checking, it has a `credentialStatus` field:

```typescript
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://w3id.org/security/suites/ed25519-2020/v1",
    "https://w3id.org/vc/status-list/2021/v1",
    "https://schemas.kya-os.ai/delegation/v1"
  ],
  "id": "urn:uuid:12345678-1234-1234-1234-123456789abc",
  "type": ["VerifiableCredential", "DelegationCredential"],
  "issuer": "did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK",
  "issuanceDate": "2025-10-17T12:00:00Z",
  "credentialSubject": {
    "id": "did:key:z6MkrWXJPkxPCuQF7RqeKZFdZqBXz3oCG7PUty5dXLKGzELj",
    "constraints": {
      "scope": {
        "allowedTools": ["read_file"],
        "allowedResources": ["/documents/*"]
      }
    }
  },
  "credentialStatus": {
    "id": "https://issuer.example.com/status/1#42",
    "type": "StatusList2021Entry",
    "statusPurpose": "revocation",
    "statusListIndex": "42",
    "statusListCredential": "https://issuer.example.com/status/1"
  },
  "proof": { ... }
}
```

### Verification Flow

```
┌──────────────┐
│ Verifier     │
│ receives     │
│ delegation   │
└──────┬───────┘
       │
       ▼
┌─────────────────────┐
│ Parse credential    │
│ status field        │
└─────────┬───────────┘
          │
          ▼
┌─────────────────────────────┐
│ Fetch StatusList2021        │
│ from statusListCredential   │
└─────────┬───────────────────┘
          │
          ▼
┌─────────────────────────────┐
│ Decompress encodedList      │
└─────────┬───────────────────┘
          │
          ▼
┌─────────────────────────────┐
│ Check bit at                │
│ statusListIndex             │
└─────────┬───────────────────┘
          │
          ├──────────┐
          │          │
          ▼          ▼
      ┌─────┐    ┌─────────┐
      │ 0   │    │ 1       │
      │ ✓   │    │ ✗       │
      └─────┘    └─────────┘
      Valid      Revoked
```

## Cascading Revocation

When you revoke a parent delegation, all child delegations should also be revoked. The framework handles this automatically:

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

// Build delegation graph
const graph = new DelegationGraph();
await graph.addDelegation(parentDelegation);
await graph.addDelegation(childDelegation1);
await graph.addDelegation(childDelegation2);

// Revoke parent and all children
await graph.revokeDelegation(
  parentDelegation.id,
  statusListManager,
  { cascade: true }
);

console.log('Parent and all children revoked');
```

**Revocation Process:**
```
Parent (index: 42)
├─ Child 1 (index: 100)
│  └─ Grandchild (index: 200)
└─ Child 2 (index: 150)

Revoke parent → cascade = true
→ Set bit 42 to 1
→ Set bit 100 to 1
→ Set bit 200 to 1
→ Set bit 150 to 1
```

## Storage Providers

### In-Memory Storage (Development)

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

const storage = new InMemoryStatusListStorage();

const manager = new StatusList2021Manager({
  issuerDid: myDid,
  statusListUrl: 'https://issuer.example.com/status/1',
  storage,
});
```

### Redis Storage (Production)

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

const redis = new Redis(process.env.REDIS_URL);

const storage = new RedisStatusListStorage({
  client: redis,
  keyPrefix: 'statuslist:',
});

const manager = new StatusList2021Manager({
  issuerDid: myDid,
  statusListUrl: 'https://issuer.example.com/status/1',
  storage,
});
```

### DynamoDB Storage (AWS)

```typescript
import { DynamoDBStatusListStorage } from '@kya-os/mcp-i-core';
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';

const dynamodb = new DynamoDBClient({ region: 'us-east-1' });

const storage = new DynamoDBStatusListStorage({
  client: dynamodb,
  tableName: 'StatusLists',
});

const manager = new StatusList2021Manager({
  issuerDid: myDid,
  statusListUrl: 'https://issuer.example.com/status/1',
  storage,
});
```

## Privacy Considerations

### Correlation Attacks

**Problem:** If each credential has its own revocation endpoint, tracking which endpoints are checked reveals which credentials are being verified.

**Solution:** StatusList2021 groups many credentials into a single list. Verifiers fetch the entire list, making it harder to correlate checks with specific credentials.

```
Bad (Individual Lists):
- Verifier checks https://issuer.com/revoke/alice-credential
  → Issuer knows Alice's credential is being used

Good (StatusList2021):
- Verifier checks https://issuer.com/status/1
  → Issuer knows someone is using a credential from this list (could be any of 100k+)
```

### Herd Privacy

The larger the status list, the better the privacy:

| List Size | Privacy Level              |
|-----------|----------------------------|
| 100       | Low (1% of list)           |
| 1,000     | Medium (0.1% of list)      |
| 10,000    | Good (0.01% of list)       |
| 100,000+  | Excellent (0.001% of list) |

**Best Practice:** Use large status lists (50k-100k credentials per list) to maximize herd privacy.

## Advanced Patterns

### Multiple Status Lists

For different purposes or to manage scale:

```typescript
// Separate lists by purpose
const revocationList = await manager.createStatusList({
  id: 'https://issuer.example.com/status/revocation/1',
  purpose: 'revocation',
});

const suspensionList = await manager.createStatusList({
  id: 'https://issuer.example.com/status/suspension/1',
  purpose: 'suspension',
});

// Separate lists by tenant
const tenantAList = await manager.createStatusList({
  id: 'https://issuer.example.com/status/tenant-a/1',
  purpose: 'revocation',
});

const tenantBList = await manager.createStatusList({
  id: 'https://issuer.example.com/status/tenant-b/1',
  purpose: 'revocation',
});
```

### Batch Revocation

Revoke multiple credentials atomically:

```typescript
await statusListManager.batchRevoke([
  42,   // credential 1
  100,  // credential 2
  250,  // credential 3
  1337, // credential 4
]);

console.log('4 credentials revoked in single atomic update');
```

### Caching Status Lists

Verifiers should cache status lists with appropriate TTLs:

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

const verifier = new CachedStatusListVerifier({
  cache: {
    ttl: 300, // 5 minutes
    maxSize: 100, // Cache up to 100 status lists
  },
  httpClient: fetch,
});

// First check: fetches from network
await verifier.checkStatus(credential1);

// Second check within TTL: uses cache
await verifier.checkStatus(credential2);
```

### Status List Rotation

Rotate status lists periodically to limit size:

```typescript
// Create new status list
const newList = await manager.createStatusList({
  id: 'https://issuer.example.com/status/2',
  purpose: 'revocation',
});

// Migrate new credentials to new list
const newIndex = await newListManager.allocateIndex();

// Archive old list (keep accessible for verification)
await manager.archiveStatusList('https://issuer.example.com/status/1');
```

## Best Practices

### 1. Index Allocation

Always allocate indexes sequentially to maximize compression:

```typescript
// Good: Sequential allocation
const index1 = await manager.allocateIndex(); // 0
const index2 = await manager.allocateIndex(); // 1
const index3 = await manager.allocateIndex(); // 2

// Bad: Random allocation
const index = Math.floor(Math.random() * 131072); // Sparse bitstring, poor compression
```

### 2. Status List Size

Choose appropriate status list sizes:

```typescript
// Small issuer (<10k credentials): Single list
const singleList = {
  id: 'https://issuer.example.com/status/1',
  purpose: 'revocation',
};

// Medium issuer (10k-100k): List per purpose
const revocationList = {
  id: 'https://issuer.example.com/status/revocation/1',
  purpose: 'revocation',
};

// Large issuer (>100k): Sharded lists
const lists = [
  'https://issuer.example.com/status/1',
  'https://issuer.example.com/status/2',
  'https://issuer.example.com/status/3',
];
```

### 3. Verification Caching

Cache status list fetches to reduce network overhead:

```typescript
const verifier = new CachedStatusListVerifier({
  cache: {
    ttl: 300, // 5 min for high-security
    // ttl: 3600, // 1 hour for lower-security
    maxSize: 100,
  },
});
```

### 4. Error Handling

Handle status checking failures gracefully:

```typescript
try {
  const result = await verifyDelegation({
    credential: delegation,
    checkStatus: true,
  });

  if (!result.verified) {
    if (result.statusRevoked) {
      throw new Error('Credential revoked');
    }
    throw new Error(`Verification failed: ${result.error}`);
  }
} catch (error) {
  if (error.code === 'STATUS_LIST_UNAVAILABLE') {
    // Status list endpoint down
    // Decision: Accept credential or reject?
    logger.warn('Status list unavailable, allowing credential');
  } else {
    throw error;
  }
}
```

### 5. Monitoring

Monitor status list health:

```typescript
const metrics = await manager.getMetrics();

console.log({
  totalCredentials: metrics.allocatedIndexes,
  revokedCredentials: metrics.revokedCount,
  revocationRate: metrics.revokedCount / metrics.allocatedIndexes,
  listSizeBytes: metrics.compressedSize,
  compressionRatio: metrics.uncompressedSize / metrics.compressedSize,
});

// Alert if revocation rate is suspiciously high
if (metrics.revocationRate > 0.5) {
  logger.alert('High revocation rate detected!');
}
```

## Complete Working Example

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

async function main() {
  // 1. Setup issuer
  const issuerDid = 'did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK';
  const statusListUrl = 'https://issuer.example.com/status/1';

  // 2. Create status list manager
  const storage = new InMemoryStatusListStorage();
  const statusListManager = new StatusList2021Manager({
    issuerDid,
    statusListUrl,
    storage,
  });

  // 3. Create status list
  const statusListVC = await statusListManager.createStatusList({
    id: statusListUrl,
    purpose: 'revocation',
  });
  console.log('✓ Status list created');

  // 4. Setup delegation issuer
  const issuer = new DelegationIssuer({
    issuerDid,
    privateKeyJwk: issuerPrivateKey,
  });

  // 5. Issue delegation with status
  const statusListIndex = await statusListManager.allocateIndex();
  const delegation = await issuer.issue({
    subjectDid: 'did:key:z6MkrWXJPkxPCuQF7RqeKZFdZqBXz3oCG7PUty5dXLKGzELj',
    constraints: {
      scope: {
        allowedTools: ['read_file'],
        allowedResources: ['/documents/*'],
      },
    },
    credentialStatus: {
      id: `${statusListUrl}#${statusListIndex}`,
      type: 'StatusList2021Entry',
      statusPurpose: 'revocation',
      statusListIndex: statusListIndex.toString(),
      statusListCredential: statusListUrl,
    },
  });
  console.log('✓ Delegation issued with status index:', statusListIndex);

  // 6. Verify delegation (should pass)
  let result = await verifyDelegation({
    credential: delegation,
    checkStatus: true,
    statusListFetcher: async (url) => {
      // In production, this would be an HTTP fetch
      return statusListVC;
    },
  });
  console.log('✓ Verification passed:', result.verified);

  // 7. Revoke credential
  await statusListManager.revokeCredential(statusListIndex);
  console.log('✓ Credential revoked');

  // 8. Verify again (should fail)
  result = await verifyDelegation({
    credential: delegation,
    checkStatus: true,
    statusListFetcher: async (url) => {
      return await statusListManager.getStatusList(statusListUrl);
    },
  });
  console.log('✗ Verification failed (revoked):', !result.verified);
  console.log('  Status revoked:', result.statusRevoked);
}

main().catch(console.error);
```

## References

- [W3C StatusList2021 Specification](https://www.w3.org/TR/vc-status-list-2021/)
- [Verifiable Credentials Data Model](https://www.w3.org/TR/vc-data-model/)
- [Privacy Considerations for StatusList2021](https://www.w3.org/TR/vc-status-list-2021/#privacy-considerations)
- [MCP-I Delegation Guide](./W3C_VC_DELEGATION_GUIDE.md)

## Next Steps

1. Read the [W3C VC Delegation Guide](./W3C_VC_DELEGATION_GUIDE.md) to understand delegation credentials
2. Review the [Compliance Matrix](./COMPLIANCE_MATRIX.md) for schema validation
3. Explore the [API Reference](./API_REFERENCE.md) for detailed API documentation
