API Keys
Most endpoints on both services are administrative: they start sessions, create credential configurations and DCQL queries, revoke credentials, and read session status. Those endpoints are authenticated with an API key, presented as a bearer token.
Endpoints the wallet calls are public by necessity — a wallet has no credentials of yours — and are secured by the session identifier in their path instead.
Configuration
Both services take the same block. The JSON key is the token; the value is a human-readable label for whoever uses it.
"integrations": {
"authentication": {
"veUpCKs6U62JYBy9n7v8ZKZUYDIeBCXQ1A8hlR57p4cLKayiAd9nKfI9NXuE9Fna": "Onboarding service", // (1)!
"Ck6U62JYBy9n7v8ZKZUYDIeBCXQ1A8hlR57p4cLKayiAd9nKfI9NXuE9FnaveUp": "Reception kiosk"
}
}
- Key: the API key itself, sent by the calling application. Value: a label, so you can tell which entry is which.
This mapping is read at startup. Adding or revoking a key requires a restart of the service.
The label is not the token
It is easy to read this block the wrong way round, because it is the inverse of most configuration. The long
opaque string on the left is the secret your application sends. Swapping them produces a service that accepts
Onboarding service as a valid API key.
Using a key
Send it as a bearer token:
curl -X POST http://localhost:8081/presentation/oid4vp/new-session \
-H 'Authorization: Bearer veUpCKs6U62JYBy9n7v8ZKZUYDIeBCXQ1A8hlR57p4cLKayiAd9nKfI9NXuE9Fna' \
-H 'Content-Type: application/json' \
-d '{ "verification_query_id": "b841f44a-d09a-4605-9ef9-b5d99a987ef7" }'
A missing or unrecognized key returns 401. If a call you expect to work returns 401, this header is the first
thing to check — every administrative example in this documentation includes it.
Which endpoints need a key
Issuer — authenticated:
POST /issuance/oid4vci/new-sessionGET /issuance/oid4vci/status/{session_id}GET /credential-configuration/{credential_configuration_id}POST /credential-configuration/createPOST /credential-configuration/remove/{credential_configuration_id}POST /credential-status/revoke/{index}
Verifier — authenticated:
POST /presentation/oid4vp/new-sessionPOST /presentation/oid4vp/static-presentationGET /presentation/oid4vp/status/{session_id}POST /verification-query/createGET /verification-query/{verification_query_id}
Everything else on both services is reached by the wallet, or is a published document such as the issuer's status list. The full picture is in the issuer and verifier API references, where each endpoint's security requirement is part of the specification.
Managing keys
- Issue one key per calling application, so you can revoke a single integration without disturbing the others. That is what the label is for.
- Generate keys with a CSPRNG and make them long. The examples above are 64 characters.
- Keep them out of
server.jsonin version control. A key sits in the same file as your database password; treat the whole file as a secret. See Going to production. - Revoking means removing the entry and restarting. There is no expiry and no per-key rate limiting.
What's Next
- Going to production: Handling these and the other secrets in
server.json. - Issuer and verifier configuration references.