Architecture · Threat model
How it works
Hermetic encrypts every byte in your browser. The server, the network, the cloud provider — none of them can read your content. We can hand them anything they ask for. What they get is ciphertext.
Ten modes · same encryption
Pick what triggers the unlock.
Every mode reuses the same skeleton: a random symmetric key encrypts the content under XChaCha20-Poly1305 with a mode-bound AAD. What changes is the unlock policy — how that key gets re-derived. Adding a mode is plugging in a different wrapKey / unwrapKey strategy.
Drop
Sealed by link
Encrypt → upload ciphertext to IPFS → share /drop/[cid]#[key]. The key lives in the URL fragment, never sent to a server.
Capsule
Sealed by time
Wrap the symmetric key with drand timelock. Nobody — us, you, the recipient, the network — can decrypt before the round arrives.
Switch
Sealed by trust
Dead-man's switch. Shamir-split the key across N trustees; if the owner goes silent past the deadline, K of N can combine.
Pact
Sealed by consensus
N-of-N agreement. Every party must combine their share — no quorum slack, no fallback. One holdout means the seal stays closed.
Halo
Sealed by hardware
Wrap the key under a WebAuthn PRF-derived KEK. Only the device with the registered passkey can produce the unwrap key.
Beacon
Sealed by event
UI gates on an EVM block height (chain decides when) plus a passphrase the owner holds (decides who). Honest about being a UI gate, not an oracle.
Echo
Sealed by reveal
Sealed-bid auction. N bidders submit content tlock-encrypted to the same close round; every bid opens at the same instant.
Sleeper
Sealed by command
Sits encrypted indefinitely. Unlocks the moment the owner clicks release; can be re-sealed at any time.
Mirror
Sealed by mutual disclosure
2-of-2 Shamir. Two halves, two holders. Neither opens alone — both must combine in the same browser session.
Sigil
Sealed by proof
Argon2id-wrapped key derivable only from the right witness. Schnorr proof primitives ship for the v2 server-blind upgrade.
What we protect against
Seven flavors of adversary.
| Adversary | Capability | What they get |
|---|---|---|
| A. Curious operator | Read access to DB + IPFS + email logs | Ciphertext, CIDs, hashed identifiers |
| B. Malicious operator | Full read-write of all infra | Same — they can break service, not break crypto |
| C. Network observer | Passive TLS metadata capture | Connection metadata; payloads are TLS-protected and ciphertext anyway |
| D. Subpoena / court order | Legal compulsion against any vendor | Whatever the operator has — which is unintelligible bytes |
| E. Single rogue trustee | Holds one Shamir share | Nothing. Zero information about the secret. |
| F. Lost recipient | Lost the URL fragment, share, or recovery code | Nothing — and that's the point. No back doors. |
| G. Compromised drand operator | One of ~19 quicknet operators turns hostile | Nothing — drand uses a t-of-n threshold (currently 14/19) |
What we don't protect
And we're honest about it.
Compromised browser
Keylogger, hostile extension, screen-record malware on the device used to seal. Plaintext is in your browser before it's encrypted; we can't help if your device leaks it.
Metadata
Server learns: file size, timestamps, who shared with whom, hashed emails, public auction titles for Echo. Trustee/member emails for Switch and Pact are stored as plaintext to enable re-notification; Mirror keeps holder emails as hashes only.
Lost keys / shares
If you lose the URL fragment, the file is gone. If trustees lose K shares, the switch is gone. If you forget the Sigil witness or the Beacon passphrase, the seal is gone. There is no escrow, no recovery. By design.
Pre-trigger collusion
K trustees who collude before a Switch fires can reconstruct the key — but the server hides the CID until status flips. Pact requires unanimous (N-of-N) consent, so one party can always withhold. Mirror is 2-of-2 by design.
Beacon UI gate
The chain anchor on Beacon is a UI gate, not a cryptographic oracle. A determined attacker can ignore the block-height check and try the passphrase early. The passphrase is the actual seal; the chain decides when the UI offers the prompt.
Sigil server-side ZK only
V1 Sigil is server-side zero-knowledge: the server never sees the witness, but the unlocking page does (the user types it in). The Schnorr stub ships now for v2 where the recipient proves knowledge to the server without revealing it.
Halo PRF availability
Halo requires an authenticator that supports the WebAuthn PRF extension (Touch ID, Windows Hello, modern Yubikeys, Android passkeys all do). Older USB authenticators may not — we fail closed with a friendly message.
Quantum adversaries
XChaCha20-Poly1305 and Argon2id remain secure. Drand timelock relies on BLS12-381 pairings — vulnerable to a sufficiently powerful quantum computer running Shor's. Schnorr secp256k1 (Sigil v2) has the same caveat. None exists today.
Vendor uptime
Pinata offline → CIDs unreachable. Vercel down → can't create accounts or check in. Public EVM RPC unreachable → Beacon can't read block height. Data stays safe (encrypted at rest), but the app stops.
Email-account compromise
Magic-link auth means your email IS the credential. An attacker who reads your inbox can sign in and trigger Sleeper releases or revoke a Switch. Use a fresh address with strong 2FA, and never let Hermetic auth share an inbox with high-value services.
Cryptographic choices
No homemade crypto. Audited primitives only.
| Primitive | Algorithm | Library |
|---|---|---|
| Symmetric AEAD | XChaCha20-Poly1305 (24-byte nonce) | libsodium |
| Password KDF | Argon2id (RFC 9106) | @noble/hashes |
| Random | CSPRNG via randombytes_buf | libsodium |
| Hash | SHA-256 | @noble/hashes |
| Secret sharing | Shamir over GF(256), 2 ≤ K ≤ N ≤ 255 | shamir-secret-sharing |
| Timelock | drand quicknet, BLS12-381 pairings | tlock-js |
| Hardware-bound KEK | WebAuthn PRF extension (HMAC-SHA256) | @simplewebauthn/* + native WebAuthn |
| Proof of knowledge | Schnorr Σ-protocol over secp256k1 + Fiat-Shamir | @noble/curves (Sigil v2 stub) |
| Chain reads (Beacon) | EVM JSON-RPC (block height) | viem |
| Sessions | HS256 JWT, HttpOnly cookie | jose |
| CSRF | Origin / Referer same-origin assertion | (in-house) |
Read more
The full story.
The bottom line
Hermetic protects against a server breach, a malicious admin, a subpoena, a hostile network. It does not protect against your own compromised device, lost keys, or vendor outages. We make that trade-off explicit. If you need stronger guarantees, fork the repo and run it yourself.