Add S3 OCSP status publishing and standalone Rust Axum responder

This commit is contained in:
2026-10-23 09:18:00 +00:00
parent 4ed14b42a7
commit 0384995570
30 changed files with 5274 additions and 5 deletions
+37 -1
View File
@@ -145,6 +145,34 @@ fingerprints and extension text. Personal API tokens (`Authorization: Bearer
kca_…`) let scripts use the REST API; tokens act as their owner, are stored
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 `ocsp/<CA certificate SHA-256>.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.
- Each CA snapshot is cached for one second with a single-flight refresh, so
concurrent requests cause at most one S3 `GetObject` per CA per second.
- If S3 is unavailable, a stale snapshot is served within the configured grace
period; otherwise the responder returns `tryLater`.
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`, or with
Compose:
```sh
docker compose --profile ocsp up --build
```
See `ocsp-responder/README.md` for the JSON layout, signer requirements and
`openssl ocsp` verification.
## REST API
OpenAPI JSON is at `/api/openapi.json`; Swagger UI at `/api/docs`.
@@ -155,7 +183,7 @@ OpenAPI JSON is at `/api/openapi.json`; Swagger UI at `/api/docs`.
| Vaults | `GET/POST /api/vaults`, `GET/PATCH/DELETE /api/vaults/{id}`, `GET/PATCH /api/vaults/{id}/settings`, `GET /api/vaults/{id}/summary`, `GET /api/vaults/{id}/options`, `GET /api/vaults/{id}/search`, `POST /api/vaults/{id}/export` |
| Keys | `GET/POST /api/vaults/{id}/keys`, `GET/PATCH/DELETE .../keys/{key_id}`, `POST .../keys/{key_id}/export` |
| Requests | `GET/POST /api/vaults/{id}/requests`, `GET/PATCH/DELETE .../{id}`, `POST .../{id}/export`, `POST .../{id}/transform/open-key`, `POST .../{id}/transform/template` |
| Certificates | `GET/POST /api/vaults/{id}/certificates`, `POST /api/vaults/{id}/certificates/preview`, `GET/PATCH/DELETE .../{id}`, `POST .../{id}/export`, `POST .../{id}/renew`, `POST .../{id}/revoke`, `POST /api/vaults/{id}/certificates/bulk-revoke`, `GET/PATCH .../{id}/ca`, `GET/POST .../{id}/revocations`, `PATCH/DELETE .../revocations/{rev_id}`, `POST .../{id}/crl`, `POST .../{id}/tls-auth`, transforms |
| Certificates | `GET/POST /api/vaults/{id}/certificates`, `POST /api/vaults/{id}/certificates/preview`, `GET /api/vaults/{id}/certificates/{ca_id}/ocsp-status`, `GET/PATCH/DELETE .../{id}`, `POST .../{id}/export`, `POST .../{id}/renew`, `POST .../{id}/revoke`, `POST /api/vaults/{id}/certificates/bulk-revoke`, `GET/PATCH .../{id}/ca`, `GET/POST .../{id}/revocations`, `PATCH/DELETE .../revocations/{rev_id}`, `POST .../{id}/crl`, `POST .../{id}/tls-auth`, transforms |
| CRLs | `GET /api/vaults/{id}/crls`, `GET/DELETE .../{crl_id}`, `POST .../{crl_id}/export` |
| Templates | `GET/POST /api/vaults/{id}/templates`, `GET/PATCH/DELETE .../{template_id}`, `POST .../{template_id}/apply`, `POST .../{template_id}/export` |
| Import | `POST /api/vaults/{id}/import` (`dry_run`, `selected`, `xca_db`) |
@@ -190,6 +218,13 @@ npm test
They use Playwright Chromium. Set `KCA_BASE_URL` to target another port, e.g.
`KCA_BASE_URL=http://localhost:8083 npm test`. See `e2e/README.md`.
OCSP responder (from `ocsp-responder/`):
```sh
cargo test
cargo run # uses OCSP_CONFIG or /etc/ocsp/responder.yaml
```
Frontend (from `web/`, with the backend running on `:8080`):
```sh
@@ -255,6 +290,7 @@ web/
src/{api,auth,model,dom}.rs
pwa/ # manifest + app-shell assets
e2e/ # Playwright browser suite (Node)
ocsp-responder/ # standalone Rust/Axum OCSP responder
```
## Limits