HTTP API
Three listeners, so the private endpoint never shares a port with the public one.
Public listener
| Endpoint | Response |
|---|---|
GET /.well-known/jwks.json, GET /jwks.json | Public JWKS of keyset ?name= (default default). |
GET /jwks/{name} | Same, keyset in the path. |
GET /healthz | Liveness; does not depend on the source. |
GET /readyz | 503 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
| Endpoint | Response |
|---|---|
GET /keyset, GET /keyset?name={name}, GET /keyset/{name} | Keyset with private members: active keys first, then retired keys. |
GET /healthz | Liveness. |
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
| Code | When |
|---|---|
401 | Basic auth configured and credentials missing or wrong. |
403 | mTLS only, and no allowed client certificate. |
404 | Unknown keyset name. |
503 | The keyset has never loaded. |
Error bodies are {"error":"…"}.