Docs
Issuance

Status Lists & Revocation

How credential revocation works with status lists

Status lists provide a scalable mechanism for revoking issued credentials. Instead of maintaining a blocklist that verifiers must query per-credential, a status list encodes the revocation status of thousands of credentials in a single, compact bitstring that verifiers can cache and check locally.

For mDoc (mso_mdoc) credentials, ISO/IEC 18013-5 second edition §12.3.6 defines two complementary mechanisms: the IETF Token Status List (bitstring) and a per-MSO identifier list. Issued mDocs reference both, and verifiers can use either. See Identifier lists below.

How status lists work

A status list is a compressed bitstring where each bit position corresponds to a credential. A 0 bit means the credential is valid; a 1 bit means it has been revoked.

Bit position:  0  1  2  3  4  5  6  7  8  9 ...
Status:        0  0  1  0  0  0  0  1  0  0 ...
                     ^                 ^
                  revoked           revoked

The status list is published at a stable URL and signed by the issuer. Verifiers fetch it periodically and check the bit at the credential's assigned position.

Serving endpoint and wire format (JWT vs CWT)

Status lists are served from a public endpoint (no authentication):

GET /credentials/status/:id
Accept: application/statuslist+cwt

The same bitstring is served in two formats from the same URL. The format is selected via the Accept header:

Accept headerFormatUsed by
application/statuslist+cwt (also the default for wildcard or missing Accept)Tag-18 COSE_Sign1 CWTmDoc verifiers (ISO 18013-5 2nd ed §12.3.6)
application/statuslist+jwt (without CWT in the same header)Signed JWT (RFC 9528 Token Status List)SD-JWT VC verifiers

Responses are served with Cache-Control: public, max-age=300. Both formats wrap an identical compressed bitstring and are signed with the same issuer key, so a verifier only needs to fetch whichever format matches its credential type.


Credential status claim

When a credential is issued, it includes a status claim that points to the status list:

mDoc (mso_mdoc)

The status is encoded in the MSO (Mobile Security Object) as part of the issuer-signed data. Per ISO/IEC 18013-5 second edition §12.3.6, the field carries both revocation references:

{
  "status": {
    "status_list": {
      "idx": 42,
      "uri": "https://api.verifiables.com/credentials/status/sl_abc123"
    },
    "identifier_list": {
      "id": "<16 random bytes>",
      "uri": "https://api.verifiables.com/credentials/identifiers/org.iso.18013.5.1.mDL"
    }
  }
}

A verifier MAY check either mechanism. Both flip together when the credential is revoked.

SD-JWT VC

The status claim is included in the JWT payload:

{
  "status": {
    "status_list": {
      "idx": 42,
      "uri": "https://api.verifiables.com/credentials/status/sl_abc123"
    }
  }
}
FieldTypeDescription
idxnumberBit position in the status list for this credential
uristringURL where the status list JWT is published

How verifiers check status

When verifying a credential, the verifier:

  1. Extracts the status claim from the credential.
  2. Fetches the status list JWT from the uri (with caching, the list changes infrequently).
  3. Verifies the status list JWT signature against the issuer's key.
  4. Decompresses the bitstring and checks the bit at position idx.
  5. If the bit is 1, the credential is revoked.

The Verifiables verification API performs this check automatically. The verification result includes the status check:

{
  "status": "valid",
  "verification": {
    "eu.europa.ec.eudi.pid.1": [
      { "status": "OK", "check": "Issuer signature valid" },
      { "status": "OK", "check": "Certificate chain valid" },
      { "status": "OK", "check": "Device signature valid" },
      { "status": "OK", "check": "Status list: not revoked" }
    ]
  }
}

If the credential has been revoked:

{
  "status": "failed",
  "verification": {
    "eu.europa.ec.eudi.pid.1": [
      { "status": "OK", "check": "Issuer signature valid" },
      { "status": "OK", "check": "Certificate chain valid" },
      { "status": "OK", "check": "Device signature valid" },
      { "status": "FAIL", "check": "Status list: credential revoked" }
    ]
  }
}

Identifier lists

The bitstring status list scales to millions of credentials in a single list, but every credential in that list shares the same URI. Verifiers that fetch the list learn the issuer's revocation state for the whole batch, which is fine for high-volume credentials but can be undesirable for low-volume ones where the per-credential bit position is correlatable across presentations.

The identifier list mechanism (ISO/IEC 18013-5 second edition §12.3.6) solves this with a different shape:

  • Each issued mDoc carries a random 16-byte id in MSO.status.identifier_list.
  • The published list contains only the identifiers of revoked credentials. A valid credential does not appear in the list at all.
  • The list is a Tag-18 COSE_Sign1 CWT served as application/identifierlist+cwt. The payload is a CBOR map; CWT claim 65530 holds { "identifiers": { <bstr id> => {...} } }.

Endpoint

GET /credentials/identifiers/:credentialType
Accept: application/identifierlist+cwt

:credentialType is the mDoc doctype (e.g. org.iso.18013.5.1.mDL). The same list covers every credential of that type issued by this issuer.

Verifying

1. Read MSO.status.identifier_list = { id, uri }
2. Fetch uri with Accept: application/identifierlist+cwt
3. Decode the COSE_Sign1; parse claim 65530.identifiers (a CBOR map)
4. If `id` is one of the keys → credential is revoked
   Otherwise → credential is valid

The Verifiables verification API checks both status_list and identifier_list automatically when present and reports the result under the REVOCATION category.

When to use which

  • Status list (bitstring): high-volume credentials, you control issuance and don't mind a shared list URI.
  • Identifier list: low-volume credentials, or when the spec/ecosystem you're targeting requires it (some mDL profiles do).

You don't have to choose: issued mDocs reference both, and verifiers pick whichever they support.


Revoking a credential

Credentials are revoked from the dashboard. Each status list shows its allocated entries, and every entry can be revoked or reinstated individually by its index. When you revoke an entry, its bit in the status list is flipped to 1 and the status list (JWT and CWT) is re-signed and re-published.

There is no public API endpoint for revoking an individual credential.


Monitoring-triggered revocation

When company monitoring detects a critical lifecycle event for a company (such as a collective proceeding, dissolution, or radiation), the platform automatically revokes the credentials associated with that company.

This works because status list entries can be linked to a SIREN at issuance time: when a monitored company reaches a terminal state, the monitoring lifecycle revokes every status list entry recorded for that SIREN. No webhook handler or API call on your side is required.


Status list properties

PropertyValue
Status list formatJWT (RFC 9528 Token Status List) or Tag-18 COSE_Sign1 CWT
Identifier list formatTag-18 COSE_Sign1 CWT (CWT claim 65530)
CompressionDEFLATE (zlib), bitstring only
Bit size1 bit per credential (valid / revoked), per ISO 18013-5 2nd ed §12.3.6.5
List capacityUp to 131,072 credentials per status list
Cache lifetime5 minutes (recommended)
Signature algorithmES256 (P-256)

With the 1-bit default, a suspended state is not representable: a credential is either valid (0) or revoked (1).

Status lists are created automatically when you issue credentials with revocation enabled. You do not need to manage them manually.