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).