Fix stale OCSP snapshots indefinitely

- Parse and validate  from snapshot JSON, reject future/missing timestamps
- Enforce snapshot age vs  in cache and stale fallback (no lifetime extension on repeat S3 reads)
- OCSP: , ,
- Remove unused  from signer
- Publisher heartbeats: , republish clean snapshots past interval, preserve dirty-only behavior and concurrency
- Config/env/docker/docs updates for heartbeat

Rolling upgrade: enable publisher heartbeats before deploying the age-enforcing responder so existing snapshots remain within the age window.
This commit is contained in:
KCA committed 2026-10-25 21:30:00 +00:00
1 parent ec42cafc28
commit d22ba6662c
12 files changed
+299 -43

No files matched your search

+17 -4
View File
@@ -27,8 +27,9 @@ vaults. The responder validates both this ID and the CA certificate fingerprint
against every downloaded snapshot.
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.
contains all certificates issued by that CA, both valid and revoked, and a
required `generated_at` timestamp. The responder never infers status from a
partial revoked-only list.
## Upgrading from fingerprint-named snapshots
@@ -97,7 +98,19 @@ build a trust store containing the CA or validate with your normal PKI tooling.
- 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`.
- `s3.stale_grace_seconds` is also the hard maximum snapshot age, measured from
`generated_at`. Expired or future-dated snapshots are rejected even when S3
remains readable; if no valid cached snapshot remains, OCSP returns
`tryLater`.
- If a refresh fails, a cached snapshot is served only while both its time since
the last successful fetch and its `generated_at` age remain within
`s3.stale_grace_seconds`.
- KCA republishes unchanged snapshots every
`KCA_OCSP_HEARTBEAT_INTERVAL_SECONDS` (default 30 seconds). Keep that interval
comfortably below the responder's `s3.stale_grace_seconds` (default 60). For
a rolling upgrade, enable publisher heartbeats before the freshness-enforcing
responder so existing snapshots remain within the age limit.
- OCSP `thisUpdate` is the snapshot's `generated_at`. `nextUpdate` is capped at
the snapshot's hard expiry, while `producedAt` is the response signing time.
- 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.