Revoke and suspend credentials
Revoke or suspend credentials you issued, using Token Status Lists (draft-ietf-oauth-status-list). EUDIPLO assigns every credential an entry in a signed status list that verifiers fetch; you change entries per issuance session. For an end-to-end walkthrough, see the revocable credentials cookbook.
Prerequisites: a credential configuration and a client with the issuance:manage role (configuration) and issuance:offer (revocation).
1. Enable status managementā
Set statusManagement: true on the credential configuration. Every credential issued afterwards carries a status reference:
{
"status": {
"status_list": {
"idx": 4711,
"uri": "https://eudiplo.example.com/issuers/membership-demo/status-management/status-list/3f1cā¦"
}
}
}
SD-JWT VCs carry it as the status claim, mDOCs in the Mobile Security Object. Credentials issued before you enabled the setting have no status entry and cannot be revoked.
Status lists use 1 bit per entry by default (STATUS_BITS=1), which only distinguishes valid and revoked. Suspending a credential on such a list is rejected with 400. If you want to suspend credentials, set bits to 2 or more in the tenant's status list settings (or STATUS_BITS) before issuing. The bits of an existing list cannot be changed.
2. Revoke or suspendā
Use the session ID returned when you created the offer:
curl -X POST "$EUDIPLO_URL/api/session/revoke" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"sessionId": "a6318799-dff4-4b60-9d1d-58703611bd23",
"credentialConfigurationId": "membership",
"status": 1
}'
| Field | Required | Description |
|---|---|---|
sessionId | yes | Issuance session that issued the credentials. |
credentialConfigurationId | no | Restrict the change to one credential type. Without it, all credentials of the session change. |
status | yes | 0 = valid, 1 = revoked, 2 = suspended. |
- The call answers
204 No Content. It updates every credential of the session and type, including all credentials of a batch; withoutcredentialConfigurationIdit updates all credentials of the session. If the session has no status entry for the type, it answers409. A value that does not fit a list's bits per entry (for example2on a 1-bit list) is rejected with400before anything is changed. - Allowed roles:
issuance:offerorissuance:manage. - Revocation is final: setting
0or2on a revoked credential is rejected with409, and nothing is changed. A suspension can be lifted (0) or turned into a revocation (1).
3. Check the resultā
Verifiers resolve status_list.uri and read the bit at idx. Status list tokens are cached:
- By default a token is re-signed only after its
ttlhas passed (STATUS_TTL, 3600 seconds). A change becomes visible to verifiers within that time. - With
immediateUpdate: true(tenant setting orSTATUS_IMMEDIATE_UPDATE), EUDIPLO re-signs the list after every change.
Verifiers may cache the token themselves until its exp.
Public endpointsā
These endpoints are wallet- and verifier-facing and have no /api prefix.
| Endpoint | Response |
|---|---|
GET /issuers/{tenant}/status-management/status-list/{listId} | Status list token. JWT (application/statuslist+jwt) by default; CWT (application/statuslist+cwt) when the Accept header contains application/statuslist+cwt. |
GET /issuers/{tenant}/status-management/status-list-aggregation | {"status_lists": ["<uri>", ā¦]} with all lists of the tenant. |
The JWT has typ: statuslist+jwt and the signing certificate in x5c; its payload contains sub (the list URI), iat, exp (iat + ttl), ttl and status_list (bits, compressed lst). With aggregation enabled (STATUS_ENABLE_AGGREGATION, default true), tokens include aggregation_uri and the authorization server metadata advertises status_list_aggregation_endpoint.
Manage status listsā
EUDIPLO allocates entries automatically: first from lists bound to the credential configuration, then from shared lists, and when all are full it creates a new shared list. Indices are assigned in random order. You only need the management API to pre-create, bind or re-key lists. All endpoints require issuance:manage.
| Endpoint | Purpose |
|---|---|
GET /api/status-lists, GET /api/status-lists/{listId} | List status lists with bits, capacity, usedEntries, availableEntries, uri and token expiresAt. |
POST /api/status-lists | Create a list: credentialConfigurationId (bind it to one type; omit for a shared list), keyChainId (signing key; default: the tenant's status list key, else its attestation key), bits (1, 2, 4 or 8), capacity (1000 to 1,000,000). |
PATCH /api/status-lists/{listId} | Change credentialConfigurationId or keyChainId (null resets to shared or default). bits and capacity are fixed. |
DELETE /api/status-lists/{listId} | Delete an unused list. Lists with entries answer 409. |
GET, PUT, DELETE /api/status-list-config | Tenant defaults: capacity (minimum 100), bits, ttl (minimum 60 seconds), immediateUpdate, enableAggregation. PUT replaces the whole object; omitted fields fall back to the environment defaults. DELETE resets to them. |
The environment defaults are STATUS_CAPACITY (10000), STATUS_BITS (1), STATUS_TTL (3600), STATUS_IMMEDIATE_UPDATE (false) and STATUS_ENABLE_AGGREGATION (true); see Environment variables. capacity and bits apply to lists created afterwards. Status lists can also be managed as files; see Configuration as code. In the web client, open Status Lists.
To keep only one valid credential per person, combine status management with activeCredentials.