Add S3 OCSP status publishing and standalone Rust Axum responder
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
# KCA OCSP responder
|
||||
|
||||
Standalone Rust/Axum responder. It reads one full JSON status snapshot per CA
|
||||
from S3-compatible object storage, caches it for one second with a single-flight
|
||||
refresh, and signs OCSP responses with a delegated responder certificate.
|
||||
|
||||
It has **no KCA database access**, no Redis access, and no KCA master key. It
|
||||
only needs:
|
||||
|
||||
- `s3:GetObject` on the configured bucket/prefix;
|
||||
- the CA certificate for each issuer;
|
||||
- a delegated OCSP signer certificate and private key for each CA. The
|
||||
responder currently accepts RSA-SHA256 and ECDSA P-256 signers in PKCS#8,
|
||||
PKCS#1 RSA, or SEC1 EC PEM form.
|
||||
|
||||
## Snapshot layout
|
||||
|
||||
KCA publishes objects as:
|
||||
|
||||
```
|
||||
<prefix>/<CA certificate SHA-256>.json
|
||||
```
|
||||
|
||||
KCA publishes these objects when `KCA_OCSP_S3_BUCKET` is configured. The JSON
|
||||
contains all certificates issued by that CA, both valid and revoked. The
|
||||
responder never infers status from a partial revoked-only list.
|
||||
|
||||
## Run locally
|
||||
|
||||
1. Create a config based on `responder.example.yaml`.
|
||||
2. Put your CA certificates and delegated signer files where the config points.
|
||||
3. Export standard AWS credentials / endpoint variables as needed.
|
||||
4. Make the signer key readable by the container user (`ocsp`, uid/gid
|
||||
`100:101` in the provided image), or mount it via a Docker secret.
|
||||
5. Run:
|
||||
|
||||
```sh
|
||||
OCSP_CONFIG=./responder.yaml cargo run
|
||||
```
|
||||
|
||||
The default listen address is `0.0.0.0:2560`.
|
||||
|
||||
## Verify with OpenSSL
|
||||
|
||||
For a CA certificate `ca.crt` and leaf certificate `leaf.crt`:
|
||||
|
||||
```sh
|
||||
openssl ocsp \
|
||||
-issuer ca.crt \
|
||||
-cert leaf.crt \
|
||||
-url http://127.0.0.1:2560/ocsp \
|
||||
-resp_text \
|
||||
-noverify
|
||||
```
|
||||
|
||||
`-noverify` skips local trust setup; the response still shows the signature
|
||||
algorithm and included responder certificate. For production verification,
|
||||
build a trust store containing the CA or validate with your normal PKI tooling.
|
||||
|
||||
## Endpoints
|
||||
|
||||
- `POST /ocsp` — `application/ocsp-request`
|
||||
- `GET /ocsp/<base64url-request>` — optional GET form
|
||||
- `GET /healthz`
|
||||
- `GET /readyz`
|
||||
|
||||
## Cache and availability
|
||||
|
||||
- Per-CA cache TTL: `s3.cache_ttl_ms` (default 1000 ms).
|
||||
- Concurrent requests for the same CA share one S3 `GetObject`.
|
||||
- If S3 fails, a previously cached snapshot is served for
|
||||
`s3.stale_grace_seconds`; otherwise the OCSP response is `tryLater`.
|
||||
- With multiple CAs, the TTL is per CA. If you need a global one-request-per-
|
||||
second limit across all CAs, that requires a shared rate limiter.
|
||||
Reference in New Issue
Block a user