The Status List Server manages and publishes status lists for credential issuers.
It allows issuers to register, publish, and update status lists, and verifiers to retrieve and validate them securely.
This service implements the Token Status List specification.
It supports both JWT and CWT formats, with cryptographic signing using multiple algorithms (ECDSA, EdDSA, RSA with SHA-256, SHA-384, SHA-512 digest algorithms).
For a detailed explanation of the architecture, see the Architecture Documentation.
Before running the server, ensure you have the following tools installed:
- Rust & Cargo (Latest stable).
- PostgreSQL: The database system used for storing status lists.
- Redis: The in-memory data structure store used for caching.
- Docker (optional, for local testing).
Clone the Repository:
git clone https://github.com/adorsys/status-list-server.git
cd status-list-serverEnvironment Variables:
Create a .env file in the root directory. Take a look at the .env.template file for an example of the required variables.
The simplest way to run the project is with docker compose:
- Execute the command below at the root of the project
docker compose up --buildThis command will pull all required images and start the server.
To start the server, execute:
cargo runBy default, the server will listen on http://localhost:8000. You can modify the host and port in the configuration settings.
- Endpoint:
GET /health - Description: Checks the health status of the server.
- Response:
200 OK: Server is running.
-
Endpoint:
POST /credentials/ -
Description: Allows issuers to register their public key and identifier for later authentication
-
Request Body
{ "issuer": "<issuer_id>", "public_key": "<public_key JWK>" }issuer: Unique identifier for the issuerpublic_key: Public key in JWK format
-
Endpoint:
POST /statuslists/publish -
Description: Allows an issuer to publish their status lists
-
Authorization: Requires a valid signed JWT Bearer token with the private key corresponding to the registered public key
-
Request Body
{ "list_id": "30202cc6-1e3f-4479-a567-74e86ad73693", "status": [ { "index": 1, "status": "INVALID" }, { "index": 8, "status": "VALID" } ] }index: Position in the status liststatus: Status value (VALID, INVALID, SUSPENDED)
-
Endpoint:
PATCH /statuslists/update -
Description: Allows an issuer to update an existing status list
-
Authorization: Requires a valid signed JWT Bearer token with the private key corresponding to the registered public key
-
Request Body:
{ "list_id": "755a0cf7-8289-4f65-9d24-0e01be92f4a6", "status": [ { "index": 1, "status": "VALID" }, { "index": 8, "status": "INVALID" } ] }list_id: UUID of the status list to updatestatus: Array of status updatesindex: Position in the status liststatus: New status value (VALID, INVALID, SUSPENDED)
-
Responses:
200 OK: Update successful400 BAD REQUEST: Invalid input data401 UNAUTHORIZED: Invalid or missing JWT Bearer token403 FORBIDDEN: Token issuer doesn't match list owner404 NOT FOUND: Status list not found500 INTERNAL SERVER ERROR: System incurred an error
- Endpoint:
GET /statuslists/{list_id} - Description: Retrieves the current status list for the requested
list_id. This endpoint is publicly accessible with no authentication required. - Headers:
Accept: Specifies the desired response formatapplication/jwt: Returns the gzip compressed status list as a JWT tokenapplication/cwt: Returns the gzip compressed status list as a CWT token- Default: Returns the gzip compressed status list as a JWT token
- Responses:
200 OK: Returns the status list in the requested format404 NOT FOUND: Status list not found406 NOT ACCEPTABLE: Requested format not supported500 INTERNAL SERVER ERROR: System incurred an error
The server uses JWT-based authentication with the following requirements:
-
Issuers must provide valid public key during registration using the
/credentials/endpoint -
All authenticated requests must include a JWT token in the Authorization header:
Authorization: Bearer <jwt_token> -
The JWT token must:
- Be signed with the private key corresponding to the registered public key
- Have
iss(issuer) claim matching the registered issuer - Have valid
exp(expiration) andiat(issued at) claims
Example JWT token header:
{
"alg": "ES256"
}Example JWT token claims:
{
"iss": "test-issuer",
"exp": 1752515200,
"iat": 1752515200
}The Status List Server is provisioned with a cryptographic certificate that is embedded into all issued status list tokens. This certificate ensures the authenticity and integrity of the tokens distributed by the server.
Automatic Issuance and Renewal:
- Certificate issuance and renewal are managed according to the configured renewal strategy.
- Every day, a cron job checks whether the certificate should be renewed based on this strategy.
- If the certificate is still considered valid according to the configured strategy, no renewal occurs; renewal is only triggered when necessary.
The server implements proper error handling and returns appropriate HTTP status codes:
400 BAD REQUEST: Invalid input data401 UNAUTHORIZED: Missing or invalid authentication token403 FORBIDDEN: Insufficient permissions404 NOT FOUND: Resource not found406 NOT ACCEPTABLE: Requested format not supported409 CONFLICT: Resource already exists500 INTERNAL SERVER ERROR: Server-side error
The server can be deployed using a containerization platform such as Docker.
A Helm chart is provided for easy deployment on Kubernetes. For detailed instructions, see the Helm Deployment Guide.
You can run the tests using the following command:
cargo testLicensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.