Revocations

Overview

A credential with a revocation‐purpose status entry indicates that its valid/invalid state is determined by a Bitstring Status List maintained on‐chain. The verifier must:

  1. Detect the presence of a revocation‐purpose credentialStatus entry.

  2. Resolve and fetch the on‐chain revocation list.

  3. Decode the bitstring and inspect the bit at the credential’s statusListIndex.

  4. Reject the VC if that bit is set (1), otherwise allow validation to continue.


Integration Point

Location in code:VcValidators.validateVc()

This is where existing validation checks occur (proof, issuer DID, subject matching). After those checks, insert the revocation validation logic described below.


Revocation Validation Steps

  1. Extract credentialStatus from the VC

    • Read the VC’s credentialStatus array.

    • Look for an entry where:

      • type equals "BitstringStatusListEntry", and

      • statusPurpose equals "revocation".

    • If no such entry exists, skip revocation validation and treat the VC as valid.

  2. Parse the statusListCredential URI

    • The credentialStatus entry contains a statusListCredential field in this format:

      ssi://{issuerDid}/{resourceId}
    • Extract:

      • {issuerDid} – the DID of the issuer, and

      • {resourceId} – the identifier of the on‐chain resource.

  3. Fetch the Revocation List from the Blockchain

    • Call:

      getLinkedResource(blockchainRpcUrl, issuerDid, resourceId)
    • If the call returns a “resource not found” error, assume no revocation list has been published for this credential. In that case, allow the VC to pass validation (revocation cannot be determined).

  4. Decode the Retrieved Data

    • The returned data is a byte array containing a compressed (gzipped) bitstring in Base64 form.

    • First decode the byte array from Base64 to obtain the raw gzip bytes.

    • Then decompress (gunzip) to recover the full bitstring as a sequence of bytes.

  5. Inspect the Bit at statusListIndex

    • From the credentialStatus entry, read the numeric statusListIndex.

    • Within the decompressed bitstring, locate the bit at that index.

      • A bit value of 1 means the credential is revoked.

      • A bit value of 0 means the credential is not revoked.

    • If the bit is 1, immediately fail validation (the VC is revoked).

    • If the bit is 0, continue with any remaining validation steps (proof verification, expiration check, etc.).


Example credentialStatus Entry

"credentialStatus": [{
  "id": "ssi://did:example:12345/statusList3#94567",
  "type": "BitstringStatusListEntry",
  "statusPurpose": "revocation",
  "statusListIndex": "94567",
  "statusListCredential": "ssi://did:example:12345/statusList3"
}]
  • statusListCredential: ssi://did:example:12345/statusList3 → split into issuerDid = did:example:12345 and resourceId = statusList3.

  • statusListIndex: 94567 → the index of the bit to check in the decompressed bitstring.


Failure Modes

  • Resource Not Found

    • If getLinkedResource(...) indicates the on‐chain revocation list does not exist, treat the VC as not revoked (do not fail).

  • Network or Decode Errors

    • If fetching or decoding the bitstring fails unexpectedly, the verifier may optionally treat the status as indeterminate and reject the VC, or fall back to a local policy. The exact behavior should align with your security requirements.


Summary

When a VC includes a revocation‐purpose status entry:

  1. Check for type: BitstringStatusListEntry and statusPurpose: revocation.

  2. Fetch the on‐chain revocation list via getLinkedResource(blockchainRpcUrl, issuerDid, resourceId).

  3. If not found, allow the VC. If found, decode from Base64 → gzip → raw bytes.

  4. Read the bit at statusListIndex:

    • 1 → credential revoked → fail validation.

    • 0 → credential not revoked → continue validation.

Add this section under your Verifier documentation to ensure all VCs with a revocation entry are properly checked before being accepted.

Last updated