Key Rotation Plan
Owner: Cryptography Specialist Last Updated: 19 June 2026 Next Review: 14 July 2026 Relates to: Key Rotation Procedure, Key Rotation Log (maintained internally; available to auditors and enterprise customers on request), Cryptography Policy
This plan enumerates every key the ISMS tracks, the target rotation cadence, and the implementation status of the rotation mechanism. Maelstrom AI records the status of each key’s rotation mechanism in one place so a policy claim always sits beside an implementation status.
The plan spans Maelstrom AI’s two platforms — Provii (zero-knowledge age verification) and downpipes (no-custody backup and disaster recovery for the Cloudflare data layer). It covers only keys that Maelstrom manages: the Provii signing keys, HMAC secrets and API tokens below, plus the two downpipes vendor-side signers (Licence Signer, Update Signer). The keys that protect downpipes backup contents — the customer-held break-glass, operational and archive-signer keys — are no-custody: they are generated and held by the customer in their own Cloudflare account, are not Maelstrom assets, and cannot be rotated by Maelstrom. Their lifecycle is a complementary user-entity control (CUEC) and is out of scope for this plan; see Cryptography Policy for the customer-held key set.
Status legend
| Symbol | Meaning |
|---|---|
| Implemented | Rotation runbook exists, has been exercised at least once, and rotation is supported without user-visible breakage beyond the documented impact. |
| Planned | Cadence is declared in policy. Runbook is drafted. Rotation would succeed but may invalidate sessions or credentials until the supporting dual-key flow lands. |
| Manual only | No automation. Rotation requires a human operator following the runbook end-to-end with downtime acceptance. |
Key inventory and status
| Key | Target cadence | Status | Delivery vehicle | Notes |
|---|---|---|---|---|
Issuer signing key (RedJubjub) in provii-issuer | Annual or on compromise | Implemented, manual only | Operator runbook at /operations/key-rotation-procedure#issuer-signing-key-rotation | JWKS transition period holds old plus new key for seven days. |
Verifier HMAC key in provii-verifier | 90 days recommended | Implemented, manual only | Operator runbook at /operations/key-rotation-procedure#customer-api-key-rotation and analogous verifier path | Dual-key acceptance not yet implemented; rotation invalidates in-flight verifier sessions. |
Customer-facing API keys issued by provii-management | 90 days recommended, customer-driven | Implemented, customer-driven | Admin Portal flow plus support path | Customer chooses cut-over window. |
| Cloudflare account API token | Annual | Implemented, manual only | Operator runbook at /operations/key-rotation-procedure#cloudflare-api-token-rotation | Requires GitHub Actions secret updates in every repo. |
| GitHub Actions secrets (derived from Cloudflare token) | Triggered by Cloudflare token rotation | Implemented, manual only | Operator runbook with gh secret set commands | Downstream of the Cloudflare token rotation. |
DOCS_SESSION_HMAC_KEY (docs interactive sandbox session HMAC) | Planned 90 days | Planned | Secrets Store (internal reference); rotation currently re-writes Version N in the store. | The docs session layer (demo-web-provii-agegate/src/docs/session.ts) runs a single-kid deployment. A rotation today invalidates all active __Host-docs_session cookies until users re-authenticate. Introducing a kid prefix on the bearer and dual-key acceptance will let rotation proceed without breaking in-flight sessions. Until that flow lands, the rotation cadence is a policy claim supported only by the single-kid emergency-rotate path. |
DOCS_ATTESTATION_ED25519_SEED (docs sandbox issuer attestation seed) | On compromise or scheduled rotation | Planned | Secrets Store (internal reference); rotation re-writes Version N. The same kid-header flow planned for DOCS_SESSION_HMAC_KEY applies. | Current rotation invalidates all in-flight sandbox attestations. |
PII_HASH_KEY (HMAC-SHA-256 key for hashed-IP and other PII indexes) | On compromise only | Implemented, manual only | Secrets Store update followed by redeploy of consumer workers | Rotation invalidates all historical PII hash equality. Documented as a design property, not a defect. |
| downpipes Licence Signer (vendor-side; signs control-plane licence tokens — asset CRYPTO-008) | Annual or on compromise | Manual only | Operator re-keys the signer in Cloudflare Secrets Store (control-plane) and re-mints active licence tokens. | Fail-open: a forged, missing or expired licence degrades to the free tier and never gates backup or restore, so a stale key carries no availability impact. No customer keys or data are protected by this key. |
downpipes Update Signer (vendor-side; signs engine update artefacts for updates.downpipes.io — asset CRYPTO-009) | Annual or on compromise | Manual only | Operator generates a new keypair offline, signs forthcoming update artefacts with it (via the offline release tooling), and publishes the rotated pinned public key with the engine release that adopts it. | Held offline by the operator; never deployed to any Worker. The engine verifies the signature against a pinned public key before applying; updates are pulled (never pushed), canary-gated with automatic rollback, and there is no phone-home. Rotating the pinned key requires a co-ordinated engine release. |
| downpipes customer-held keys (break-glass, operational, archive-signer) | — | Not applicable (no-custody; customer-controlled) | Not Maelstrom-managed. Customer-generated via a guided in-browser key ceremony; rotation, if any, is performed by the customer. | Out of scope for this plan. Maelstrom holds no copy and cannot rotate these keys by design; safeguarding them is a CUEC borne by the customer. See Cryptography Policy. |
Planned work to close the Planned items
- Implement the
kidprefix on the__Host-docs_sessionbearer indemo-web-provii-agegate/src/docs/session.ts. Accept bearers minted under either the current or the previous generation ofDOCS_SESSION_HMAC_KEY. - Implement the
kidprefix on sandbox attestations signed withDOCS_ATTESTATION_ED25519_SEED. Verifier-side acceptance reads thekidand selects the matching verification key from a two-slot keyring. - Add a rotation cron entry (or documented quarterly calendar invite with runbook link) that exercises
DOCS_SESSION_HMAC_KEYrotation on the 90-day target cadence. Populate the key rotation log on each exercise. - After the first real rotation, advance the status of both planned entries above from Planned to Implemented.
Policy-to-implementation reconciliation
The 90-day rotation cadence for DOCS_SESSION_HMAC_KEY is a policy target. The implementation sits behind the planned work above. This plan is the ISMS artefact that audits the claim; the design proposals under internal docs are engineering artefacts, not ISMS artefacts.
If the dual-kid flow is not available by the first scheduled 90-day rotation window, Maelstrom AI will perform a single-kid rotation using the emergency path and accept the user-visible session invalidation as a planned downtime event. Letting the key age past 90 days is not acceptable under the declared cadence.
Change log
| Version | Date | Summary |
|---|---|---|
| 1.1 | 2026-06-19 | downpipes added as second in-scope platform; the legacy backup worker retired in favour of self-hosted downpipes. Added the two downpipes vendor-side signers (Licence Signer, Update Signer) to the key inventory and recorded the no-custody boundary — customer-held downpipes keys are not Maelstrom-managed and are out of scope for this plan. |
| 1.0 | 2026-04-14 | Initial plan covering the DOCS_SESSION_HMAC_KEY rotation mechanism and the wider key inventory. |