Cryptography Policy

Cryptographic algorithm selection and key management

Public

Purpose

This policy defines approved cryptographic algorithms, key management practices, and security requirements for cryptographic operations across Maelstrom AI’s two platforms — Provii (privacy-preserving age verification) and downpipes (no-custody backup and disaster recovery for the Cloudflare data layer).

The two platforms have distinct cryptographic profiles:

  • Provii uses zero knowledge proofs, commitments and signatures to verify age without exposing personal data; Maelstrom operates the Provii verification infrastructure and manages the associated signing keys.
  • downpipes seals customer backups with post-quantum hybrid encryption under customer-held keys, in the customer’s own Cloudflare account. Because downpipes is no-custody, the keys that protect backup contents are generated and held by the customer and are not Maelstrom-managed; Maelstrom holds only two vendor-side signing keys (licence and update — see Key Management). Maelstrom’s own Cloudflare estate is backed up by our own production instance of downpipes, in which Maelstrom holds the operator keys (we dogfood our own product).

The Provii-specific standards below (zero knowledge proofs, commitments, credential signatures) apply to the Provii platform; the downpipes Cryptography section sets out the downpipes profile. Shared standards — transport encryption, data at rest, hashing, key management discipline — apply to both platforms.

Cryptographic Standards

Zero knowledge Proofs

Algorithm: Groth16 Curve: BLS12-381 pairing-friendly elliptic curve Library: bellman 0.14 Use: Age verification proofs

Rationale: Industry-standard, well-audited, optimal proof size

Commitments

Algorithm: Pedersen commitments Curve: Jubjub (embedded in BLS12-381) Library: jubjub 0.10 Use: Hiding date-of-birth in credentials; commitment opened inside ZKP circuit

Rationale: Perfectly hiding, computationally binding; compatible with Groth16 circuit over BLS12-381

Digital Signatures

Credential Signing:

  • Algorithm: RedJubjub (custom variant)
  • Curve: Jubjub (embedded in BLS12-381)
  • Library: redjubjub 0.8
  • Use: Issuer signs age credentials

Issuer Attestation:

  • Algorithm: Ed25519
  • Library: ed25519-dalek 2.x
  • Use: Issuers sign attestation payloads proving user identity verification

API Authentication:

  • Algorithm: HMAC-SHA256
  • Key size: 256 bits minimum
  • Use: Expert relying party API authentication (provii-verifier, provii-issuer); also used in provii-verifier hosted mode for session token signing and internal service communication (hosted mode RP auth uses pk_ keys + Origin validation)

WebAuthn Verification:

  • Algorithm: ECDSA over P-256 (NIST curve)
  • Library: @simplewebauthn/server (TypeScript, admin-portal)
  • Use: WebAuthn passkey verification in admin-portal

API Key Hashing

Algorithm: Argon2id (RFC 9106) Library: argon2 0.5 Use: Hashing API keys at rest in provii-verifier and provii-issuer; designed so that stored key material cannot feasibly be reversed

Envelope Encryption

Algorithm: AES-256-GCM Library: aes-gcm 0.10 Use: Envelope encryption of HMAC secrets at rest in KV storage; Master Encryption Key (MEK) held in Cloudflare Secrets Store, Data Encryption Keys (DEK) stored alongside encrypted secrets

Hashing

Approved Algorithms:

  • BLAKE2 / BLAKE2s (preferred for ZKP)
  • SHA-256 (API authentication, checksums)
  • SHA-384 (SRI hashes for browser artifacts)

Prohibited: MD5, SHA-1 (cryptographically broken)

Exception: HMAC-SHA1 is permitted exclusively for YubiKey officer authentication in the provii-issuer. This hardware-enforced constraint cannot be changed as YubiKey 5 series implements HMAC-SHA1 in firmware. The HMAC construction mitigates SHA-1’s collision weaknesses.

Transport Encryption

TLS 1.3 preferred for all external communications

  • Minimum: TLS 1.2 (permitted if TLS 1.3 unavailable)
  • Cloudflare handles TLS termination
  • Certificate management: Automatic (Cloudflare Universal SSL)

Data at Rest

Full disk encryption required:

  • macOS: FileVault (AES-256)
  • Windows: BitLocker (AES-256)
  • Linux: LUKS (AES-256)

Cloudflare KV:

  • Encrypted at rest by Cloudflare
  • Transparent to applications

downpipes Cryptography

downpipes is no-custody backup and disaster recovery for the Cloudflare data layer. The backup engine runs in the customer’s own Cloudflare account, under the customer’s own keys; Maelstrom holds no customer keys, data or Cloudflare tokens. This section sets out the cryptography specific to downpipes.

Archive Sealing

Algorithm: Post-quantum hybrid encryption Use: Sealing backup archives before they leave the source tenant Where: In the customer’s own Cloudflare account, by the in-tenant engine

The engine reads sources (Workers KV, D1, R2, Secrets Store and zone/account configuration surfaces) and seals each archive with post-quantum hybrid encryption before fanning it out (3-2-1) to two or more customer-controlled destinations. Archives are sealed under customer-held keys; no archive is readable by anyone without those keys.

Customer-Held Keys (No-Custody)

Because downpipes is no-custody, the keys that protect backup contents are generated and held by the customer, not by Maelstrom. They are not Maelstrom assets and are not managed under the Key Management section below.

Key set (customer-held):

  • Break-glass key
  • Operational key(s)
  • Archive-signer key

Generation: Customer-generated via a guided in-browser key ceremony Storage: Offline, by the customer — guidance provided for encrypted USB, password manager, or Shamir split; a printed recovery sheet is produced during the ceremony Posture: Default two-recipient posture, with a strict break-glass-only opt-out Recovery: The MIT-licensed downpipe offline reader restores from archive bytes plus the customer’s offline key alone — no vendor, no network

No-custody boundary. Maelstrom cannot decrypt, recover or rotate customer downpipes keys — by design. Safeguarding the break-glass, operational and archive-signer keys is a complementary user-entity control (CUEC) borne by the customer.

Vendor-Side Signing Keys

Maelstrom holds exactly two vendor-side signing keys for downpipes. Neither protects customer data; both are documented in the Asset Register (CRYPTO-008, CRYPTO-009).

downpipes Licence Signer:

  • Use: Signs downpipes licence tokens issued by the vendor-operated control-plane
  • Storage: Cloudflare Secrets Store (control-plane)
  • Failure mode: Fail-open — a forged, missing or expired licence degrades to the free tier and never gates backup or restore, so compromise is contained

downpipes Update Signer:

  • Use: Signs engine update artefacts for the signature-pinned update channel (updates.downpipes.io)
  • Storage: Held offline by the operator; never deployed to any Worker
  • Verification: The engine verifies the update signature against a pinned public key before applying; updates are pulled (never pushed), canary-gated with automatic rollback, and there is no phone-home

Maelstrom’s Own Estate (Dogfooding)

Maelstrom’s entire Cloudflare estate is backed up by our own production instance of downpipes (we run downpipes as a customer of our own product). In that deployment Maelstrom holds the operator keys (break-glass, operational, archive-signer), created through the same in-browser key ceremony and stored offline; archives are sealed with post-quantum hybrid encryption and fanned out 3-2-1 to Maelstrom-controlled destinations. See Cloudflare Backup Evidence.

Key Management

This section governs the cryptographic keys Maelstrom manages: Provii signing keys and HMAC secrets, API tokens, and the two downpipes vendor-side signers (Licence Signer, Update Signer — see Vendor-Side Signing Keys). Customer-held downpipes keys (break-glass, operational, archive-signer) are no-custody and out of scope here — see Customer-Held Keys (No-Custody).

Signing Key Lifecycle

Generation:

  • Generated using cryptographically secure random number generator
  • Offline generation preferred
  • Ceremony documented (who, when, how)
  • Verification key published to JWKS

Storage:

  • Production: Cloudflare Workers KV with AES-256-GCM envelope encryption; Master Encryption Key (MEK/KEK) held in Cloudflare Secrets Store, separate from encrypted signing keys
  • Backup: Encrypted offline storage (physical security)
  • Never in source code or logs

Rotation:

  • Schedule: Annually
  • Trigger: On compromise or suspected compromise
  • Process: Generate new key, update JWKS, mark old key status as Deprecated in KV storage
  • Grace period: 30 days for relying parties to update

Destruction:

  • Cryptographic erasure (overwrite with random data)
  • Physical destruction for offline backups (after retention period)

HMAC Secrets

Generation: Cryptographically secure random (256 bits minimum) Storage: Cloudflare KV with AES-256-GCM envelope encryption; Master Encryption Keys held in Cloudflare Secrets Store Rotation: Annually or on compromise Distribution: Secure channel only (never email)

API Keys

Cloudflare API Tokens:

  • Scoped minimally (specific permissions only)
  • Stored in GitHub Secrets (for CI/CD) or password manager
  • Rotation: Annually or on suspected compromise

GitHub Personal Access Tokens:

  • Scoped to required repos/actions only
  • Expiration: 90 days maximum
  • Stored in password manager
  • Rotation: At expiration or on compromise

Cryptographic Implementation

Development Guidelines

Use established libraries:

  • Never implement cryptography from scratch
  • Use well-audited, maintained libraries
  • Keep dependencies updated

Approved Libraries (Rust):

  • bellman, bls12_381, jubjub, redjubjub (ZKP and signature primitives)
  • ed25519-dalek (Ed25519 attestation signatures)
  • blake2, sha2, sha1 (sha1 for YubiKey HMAC only)
  • hmac, hkdf (HMAC-SHA256 authentication, key derivation)
  • aes-gcm (AES-256-GCM envelope encryption for secrets at rest)
  • argon2 (Argon2id for API key hashing)
  • subtle (constant-time comparisons)
  • zeroize (secret memory erasure)
  • rand, rand_core, getrandom (cryptographically secure random)
  • p256, ecdsa (P-256 ECDSA primitives, available for future use)

Approved Libraries (JavaScript/TypeScript):

  • @simplewebauthn/server (WebAuthn passkey verification in admin-portal)
  • Web Crypto API (browser)
  • Node.js crypto module

Testing

Required for cryptographic code:

  • Unit tests (correctness)
  • Property-based tests (proptest)
  • Fuzzing (cargo-fuzz)
  • Known-answer tests (test vectors)

Never:

  • Use weak RNGs for crypto (Math.random, etc.)
  • Implement custom crypto without expert review
  • Disable crypto for debugging

Quantum Resistance

The two platforms sit at different points on the post-quantum curve:

Provii — current primitives (Groth16/BLS12-381, RedJubjub, Pedersen commitments, Ed25519) are NOT quantum-resistant.

  • Monitoring: Track NIST post-quantum standardisation
  • Timeline: Plan migration when post-quantum standards mature
  • Estimated: 2030-2035 timeframe for practical quantum threat
  • Near-term: BLS12-381 provides 128-bit security, sufficient for foreseeable future
  • Migration plan: see the Post-Quantum Cryptography Roadmap

downpipes — backup archives are already sealed with post-quantum hybrid encryption (see Archive Sealing), mitigating the store-now-decrypt-later threat to backed-up data under the no-custody model.

Compliance

  1. Australian Signals Directorate (ASD) guidance reviewed
  2. NIST SP 800-series consulted
  3. Industry best practices followed
  1. provii-crypto documentation
  2. Statement of Applicability - Control A.8.24 (Use of Cryptography)
  3. Access Control Policy
  4. Post-Quantum Cryptography Roadmap - Provii PQC migration plan
  5. Asset Register - CRYPTO-008/009 (downpipes vendor-side signers)
  6. Cloudflare Backup Evidence - downpipes dogfooding evidence

Document Information

  • Version. 1.2
  • Effective Date. 2025-01-13
  • Last Updated. 2026-06-19
  • Owner. ISMS Owner
  • Maintained By. Cryptography Specialist
  • Review Frequency. Annually
  • Next Review. 2026-11-21
  • Classification. Public
  • Change History. v1.2 (2026-06-19) — downpipes added as second in-scope platform; the legacy backup worker retired in favour of self-hosted downpipes.