Skip to content

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"
  }
}
  1. 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-session
  • GET /issuance/oid4vci/status/{session_id}
  • GET /credential-configuration/{credential_configuration_id}
  • POST /credential-configuration/create
  • POST /credential-configuration/remove/{credential_configuration_id}
  • POST /credential-status/revoke/{index}

Verifier — authenticated:

  • POST /presentation/oid4vp/new-session
  • POST /presentation/oid4vp/static-presentation
  • GET /presentation/oid4vp/status/{session_id}
  • POST /verification-query/create
  • GET /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.json in 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