# 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: ``` /.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 (`65532:65532` in the published scratch 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`. The published image is built by Gitea Actions on `release/*` tags: ```sh docker run --rm -p 2560:2560 \ -v "$PWD/responder.yaml:/etc/ocsp/responder.yaml:ro" \ -v "$PWD/ca:/etc/ocsp/ca:ro" \ -v "$PWD/signers:/etc/ocsp/signers:ro" \ -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY \ gitea.woggioni.net/woggioni/kca-ocsp:latest ``` It runs `FROM scratch` and contains only a statically linked musl executable and a CA bundle for outbound S3 HTTPS. There is no shell or package manager in the image. ## 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/` — 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.