Skip to content

Cryptography

Edition: Community and Enterprise

Every key sealfix uses, what it protects and where it lives. sealfix uses standard constructions from maintained libraries only; it implements no cryptographic primitive of its own.

The envelope

Each set of values, and each before-image, is sealed in its own envelope.

flowchart LR
    V["Values or<br/>before-image"] -->|"AES-256-GCM<br/>fresh 256-bit key,<br/>context as AAD"| C["Ciphertext"]
    K["Data key<br/>one per envelope"] -->|"HPKE, RFC 9180<br/>DHKEM P-256, HKDF-SHA256"| W["Wrapped key"]
    PK["Executor public key"] --> W
    C --> E[("Envelope")]
    W --> E
    classDef k fill:#F6E8EB,stroke:#7D1D2F,stroke-width:2px,color:#13202D
    classDef b fill:#E9EEF6,stroke:#23407A,color:#13202D
    class K,PK k
    class V,C,W,E b
  • Body: AES-256-GCM with a fresh 256-bit data key and a random 96-bit nonce. The request, the revision and the purpose are bound as associated data, so an envelope cannot be moved to another request.
  • Key wrapping: HPKE (RFC 9180) base mode, DHKEM(P-256, HKDF-SHA256) with AES-256-GCM, to the executor's public key.
  • Write-once: a sealed revision cannot be changed in the store by any database role.

Keys

Key Algorithm Held by Protects
Executor key pair P-256 (HPKE) Private: executor only. Public: the web application Every data key
Data key AES-256-GCM, 256-bit Nobody: used once, then only stored wrapped One envelope
Checkpoint signing key Ed25519 Executor The audit chain's signed checkpoints (C2SP signed note)
Approver passkey EdDSA, ES256 or RS256 (WebAuthn) The approver's authenticator Signed approvals
Session token 256 random bits Browser cookie (HttpOnly, SameSite=Strict, Secure); only its SHA-256 on the server The signed-in session
Bootstrap administrator password scrypt (N = 2^15, r = 8, p = 1) The API's environment, as a hash The break-glass account
Git signing key SSH, Ed25519 recommended gitsync Every commit it writes
Webhook secret HMAC-SHA256, Standard Webhooks v1 The notifier Authenticity of each notification

With the Enterprise edition, the executor's keys can live in a PKCS#11 HSM, created in the token and never extractable.

Hashes that bind decisions

Every approval binds digests of what it approved: the approval contract (template, target, row limit, ticket), the sealed values, the dry run's effects and the risk assessment. The executor recomputes them before it decrypts anything, and refuses to run if any differs.

Planned

A migration plan to post-quantum key encapsulation is documented in the repository (docs/explanation/post-quantum.md).