Key rotation policy
This page documents the key management and rotation policy for all cryptographic material CloakAPI controls. For keys controlled by the customer (e.g. their own LLM provider API keys stored via BYOK), see the Gateway authentication page.
Receipt signing keys
Receipt signing keys are used to produce the ECDSA signatures on signed receipt envelopes. They are the most security-critical keys in the system.
| Property | Value |
|---|---|
| Algorithm | ECDSA P-256 (secp256r1) |
Key ID (kid) format | gw-{region}-{YYYY}-q{quarter} — example: gw-prod-2026-q2 |
| Rotation period | Every 90 days |
| Overlap window | New key activated 7 days before old key stops signing, so in-flight receipts are always produced by the live key |
| Retention for verification | Old public keys remain in the JWKS indefinitely after rotation, so historic receipts always verify |
| Post-rotation status | Old kid entries are marked x-cloakapi-active: false in the JWKS — they can no longer sign new receipts but remain valid for historical verification. Routine rotation never sets revoked: true; that claim is reserved for a compromised key, which verifiers must reject (see below). |
JWKS endpoint
https://api.cloakapi.io/api/.well-known/cloakapi-receipt-pubkeys.jwksThis endpoint returns a standard JWK Set. Each entry includes:
kid— key identifier ingw-{region}-{YYYY}-q{quarter}formatkty—"EC"crv—"P-256"x,y— public key coordinates (base64url)use—"sig"x-cloakapi-active—trueon the current signing key,falseon keys that have been rotated out (which still verify their historical receipts)revoked— present andtrueonly if a key was compromised and withdrawn; verifiers must reject receipts signed by such a key. Routine rotation does not set it.
Example entry for an active key:
{ "kid": "gw-prod-2026-q2", "kty": "EC", "crv": "P-256", "use": "sig", "x-cloakapi-active": true, "x": "<base64url>", "y": "<base64url>"}Example entry for a rotated-out key (inactive, but still verifies historical receipts):
{ "kid": "gw-prod-2026-q1", "kty": "EC", "crv": "P-256", "use": "sig", "x-cloakapi-active": false, "x": "<base64url>", "y": "<base64url>"}Example entry for a compromised key (withdrawn — verifiers must reject receipts signed by it):
{ "kid": "gw-prod-2025-q4", "kty": "EC", "crv": "P-256", "use": "sig", "x-cloakapi-active": false, "revoked": true, "x": "<base64url>", "y": "<base64url>"}Rotation schedule
Keys are named after the quarter they are activated. A gw-prod-2026-q2 key begins signing in Q2 2026 (April) and is superseded in Q3 2026 (July). The overlap window means receipts signed near the boundary may carry either kid.
Customer API keys
Customer API keys authenticate requests to the CloakAPI gateway.
| Property | Value |
|---|---|
| Rotation | User-driven — rotated on demand from the dashboard or via the management API |
| Grace period | None — rotation deactivates the old key immediately and atomically (the new key is created and the old key deactivated in the same transaction). Have the new key deployed before you rely on it. |
| Format | cloak_live_<43 url-safe base64 chars> (32 random bytes); all keys carry the cloak_ prefix |
| Storage | Keys are stored as SHA-256 hashes server-side. The plaintext is shown once at creation and not recoverable |
| Revocation | Immediate — a revoked key fails with HTTP 401 within seconds of revocation |
| Expiry | No automatic expiry |
Rotation procedure
- In the dashboard go to Settings → API keys → Rotate.
- A new key is generated and displayed once — copy it immediately.
- The old key is deactivated at the moment of rotation — there is no grace window. Deploy the new key to your application right away.
- If a key is believed compromised, Revoke and Rotate are equally immediate; either invalidates the old key at once.
HSM / KMS path
Key ID reference table
kid | Status | Notes |
|---|---|---|
gw-prod-2026-q2 | Active | Current signing key, Q2 2026 |
| Earlier keys | Inactive (x-cloakapi-active: false) | Available in JWKS for historical receipt verification |
This table reflects the state at documentation publish time. The JWKS endpoint is always authoritative.