Documentation menu

HTTP API

Three listeners, so the private endpoint never shares a port with the public one.

Public listener

EndpointResponse
GET /.well-known/jwks.json, GET /jwks.jsonPublic JWKS of keyset ?name= (default default).
GET /jwks/{name}Same, keyset in the path.
GET /healthzLiveness; does not depend on the source.
GET /readyz503 until every keyset has loaded, and when one is older than max_stale.

Headers: Content-Type: application/jwk-set+json, Cache-Control: public, max-age=<jwks_max_age>, ETag.

Private listener

EndpointResponse
GET /keyset, GET /keyset?name={name}, GET /keyset/{name}Keyset with private members: active keys first, then retired keys.
GET /healthzLiveness.

Headers: Content-Type: application/jwk-set+json, Cache-Control: no-store, ETag.

Admin listener

GET /metrics (Prometheus), GET /healthz, GET /readyz.

Conditional requests

Both documents carry a strong ETag. A matching If-None-Match returns 304 Not Modified with no body.

Errors

CodeWhen
401Basic auth configured and credentials missing or wrong.
403mTLS only, and no allowed client certificate.
404Unknown keyset name.
503The keyset has never loaded.

Error bodies are {"error":"…"}.