Publish OCSP snapshots through Redis
This commit is contained in:
@@ -193,33 +193,34 @@ only as SHA-256 digests, and cannot mint/revoke tokens.
|
||||
|
||||
## OCSP responder
|
||||
|
||||
KCA can publish full per-CA certificate-status snapshots to any S3-compatible
|
||||
bucket and ships a standalone Rust/Axum responder on port `2560`.
|
||||
KCA publishes full per-CA certificate-status snapshots to the same Redis
|
||||
instance and logical database used for sessions, and ships a standalone
|
||||
Rust/Axum responder on port `2560`.
|
||||
|
||||
- KCA publishes `ocsp/<KCA CA UUID>.json` whenever certificates are issued,
|
||||
renewed, revoked, deleted or imported. Revocation reasons are
|
||||
included; this is a full status snapshot, not a revoked-only list.
|
||||
- The responder has no Postgres/Redis/KCA master-key access. It only reads the
|
||||
configured S3 prefix and uses a delegated OCSP signing certificate/key per
|
||||
CA.
|
||||
- KCA publishes `ocsp:<KCA CA UUID>` whenever certificates are issued, renewed,
|
||||
revoked, deleted or imported. Revocation reasons are included; this is a full
|
||||
status snapshot, not a revoked-only list. OCSP keys are separate from session
|
||||
keys through their prefix.
|
||||
- The responder has no Postgres or KCA master-key access. It reads only OCSP
|
||||
snapshots from Redis and uses a delegated OCSP signing certificate/key per
|
||||
CA. Where Redis ACLs are available, restrict the responder to `ocsp:*` so it
|
||||
cannot read session entries.
|
||||
- Each CA snapshot is cached for one second with a single-flight refresh, so
|
||||
concurrent requests cause at most one S3 `HeadObject` plus conditional
|
||||
`GetObject` sequence per CA per second. The ETag condition keeps the body and
|
||||
expiry metadata from different object versions from being combined.
|
||||
concurrent requests share one atomic Redis `GET` + `PTTL` lookup per CA.
|
||||
- The publisher refreshes unchanged snapshots every 30 seconds by default and
|
||||
sets each object's `Expires` header 60 seconds in the future. The responder
|
||||
rejects expired objects even when S3 is readable and returns `tryLater` when
|
||||
no unexpired snapshot is available. S3 does not delete objects at `Expires`.
|
||||
sets each key's expiry to 60 seconds. A missing or expired snapshot produces
|
||||
`unknown`; Redis failures produce `tryLater` when no unexpired cached
|
||||
snapshot remains.
|
||||
- OCSP `thisUpdate` is the response time and `nextUpdate` never extends beyond
|
||||
the snapshot's hard expiry.
|
||||
the snapshot's Redis expiry.
|
||||
- Gitea Actions publishes `gitea.woggioni.net/woggioni/kca-ocsp` on the same
|
||||
`release/*` tags as the server image. The responder image is a statically
|
||||
linked musl executable running `FROM scratch` with only the CA bundle.
|
||||
|
||||
Enable publishing in KCA with `KCA_OCSP_S3_BUCKET` and the other
|
||||
`KCA_OCSP_*` variables in `server/.env.example`. Run the responder with a
|
||||
configuration derived from `ocsp-responder/responder.example.yaml`, setting
|
||||
each issuer's `ca_id` to its CA certificate UUID in KCA, or with Compose:
|
||||
Configure `REDIS_URL` and the other `KCA_OCSP_*` variables in
|
||||
`server/.env.example`. Run the responder with a configuration derived from
|
||||
`ocsp-responder/responder.example.yaml`, setting each issuer's `ca_id` to its
|
||||
CA certificate UUID in KCA and using the same Redis URL, or with Compose:
|
||||
|
||||
```sh
|
||||
docker compose --profile ocsp up --build
|
||||
|
||||
Reference in New Issue
Block a user