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 revokedThe 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+cwtThe same bitstring is served in two formats from the same URL. The format is selected via the Accept header:
| Accept header | Format | Used by |
|---|---|---|
application/statuslist+cwt (also the default for wildcard or missing Accept) | Tag-18 COSE_Sign1 CWT | mDoc 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"
}
}
}| Field | Type | Description |
|---|---|---|
idx | number | Bit position in the status list for this credential |
uri | string | URL where the status list JWT is published |
How verifiers check status
When verifying a credential, the verifier:
- Extracts the
statusclaim from the credential. - Fetches the status list JWT from the
uri(with caching, the list changes infrequently). - Verifies the status list JWT signature against the issuer's key.
- Decompresses the bitstring and checks the bit at position
idx. - 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
idinMSO.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 claim65530holds{ "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 validThe 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
| Property | Value |
|---|---|
| Status list format | JWT (RFC 9528 Token Status List) or Tag-18 COSE_Sign1 CWT |
| Identifier list format | Tag-18 COSE_Sign1 CWT (CWT claim 65530) |
| Compression | DEFLATE (zlib), bitstring only |
| Bit size | 1 bit per credential (valid / revoked), per ISO 18013-5 2nd ed §12.3.6.5 |
| List capacity | Up to 131,072 credentials per status list |
| Cache lifetime | 5 minutes (recommended) |
| Signature algorithm | ES256 (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.