Beltic logo
Advanced Topics

Status Lists & Revocation

Complete guide to Status List 2021 implementation and revocation checking.

How credential revocation works using W3C Status List 2021.

Status List 2021 Mechanism

Credentials reference a bitstring index for revocation checking:

{
  "credentialStatus": {
    "id": "https://beltic.com/status/dev-credentials.json#12345",
    "type": "StatusList2021Entry",
    "statusListCredential": "https://beltic.com/status/dev-credentials.json",
    "statusListIndex": "12345"
  }
}

Checking Status

import { parseStatusEntry, decodeStatusList, isBitSet, StatusListCache } from '@beltic/sdk';

const entry = parseStatusEntry(credential.credentialStatus);
const cache = new StatusListCache(300000);  // 5-minute TTL

const statusList = await cache.fetch(entry.statusListCredential);
const isRevoked = isBitSet(statusList, entry.statusListIndex);

if (isRevoked) {
  throw new Error('Credential has been revoked');
}

For Issuers

Publishing Status Lists

// Bitstring: one bit per credential
const bitstring = new Uint8Array(Math.ceil(maxCredentials / 8));

// Revoke credential at index 12345
const index = 12345;
bitstring[Math.floor(index / 8)] |= (1 << (index % 8));

// Compress and encode
const compressed = gzip(bitstring);
const encoded = base64(compressed);

// Publish as JSON
const statusList = {
  "@context": ["https://w3.org/2018/credentials/v1"],
  "type": "StatusList2021Credential",
  "id": "https://beltic.com/status/dev-credentials.json",
  "encodedList": encoded
};

Timely Updates

  • Update status lists within 5 minutes of revocation
  • Use CDN for global distribution
  • Set appropriate cache headers

For Verifiers

Caching Strategy

  • Short TTL (5-15 minutes)
  • Balance freshness vs performance
  • Implement fallback for service outages

Graceful Degradation

try {
  const isRevoked = await checkStatus(credential);
  if (isRevoked) reject();
} catch (error) {
  // Status service down - apply risk-based policy
  if (highRiskOperation) {
    reject();  // Fail closed
  } else {
    logWarning('Status check failed, allowing with audit');
    allow();   // Fail open with logging
  }
}

See Also