The short version
Your tasks are encrypted on your device, with a key derived from your passphrase, before anything is ever written to storage — local or synced. That key is never transmitted anywhere. The server, if you turn on sync, receives and stores only the encrypted result. There's no "we could technically read your tasks if we wanted to" available to us, because there's no key on our end to do it with.
What "encrypted" means here, specifically
Each task is encrypted with AES-256-GCM — an authenticated cipher, so a tampered ciphertext fails to decrypt rather than silently decrypting into garbage. The key used isn't your passphrase directly; your passphrase is run through PBKDF2 (100,000+ iterations) to derive a key-encryption key, which in turn unwraps the actual per-vault data-encryption key. That extra layer means changing your passphrase later doesn't require re-encrypting every task — only re-wrapping one key.
This is meaningfully different from what most "encrypted" task apps mean. Encrypted in transit (HTTPS to their server) and encrypted at rest (the disk is encrypted, but the company holds the key) are both table stakes and both still let the company read your data whenever it wants to, or whenever a subpoena asks it to. Haven's encryption happens before a task leaves your browser, using a key that never leaves it either.
// You type: "Call the accountant about Q3 filing" // This is the record that reaches storage — local or synced: { "id": "a1f9c3...", "iv": "N3k2pQr8vXm1...", "ciphertext": "8f2e9c1a4b7d3f6e0a2c5b9d8e1f4a7c...", "updatedAt": 1754521600000 } // No title. No notes. No project name. Nothing readable.
Getting in without a "forgot password" link
Real encryption means Haven genuinely cannot reset your passphrase for you — there's no button that magically restores access, because that would require us to hold a key we deliberately don't have. Instead there are real, working alternatives, each unlocking the same data through a different door:
- A one-time recovery code, shown once at setup — a second way in, stored by you, not us.
- Social recovery — that recovery code split via Shamir's Secret Sharing among people you trust (k-of-n), so no single person can reconstruct it alone, but a quorum can help you back in.
- Passkey (WebAuthn) unlock — your device's own biometrics/security key as a second, parallel wrap of the same underlying key, alongside your passphrase, not instead of it.
The honest floor: lose your passphrase and the recovery code (and never set up passkey or social recovery), and the data is gone. Not "gone until you call support" — actually gone. That's the real cost of encryption nobody but you can undo.
What a compromised server would actually get
The sync server (optional, off by default) is a dumb encrypted-blob store — it never
decrypts anything, never sees a key, and authenticates you with a random bearer token, not
an identity tied to an email or account. If it were ever breached, an attacker gets a pile of
ciphertext and no way to read it. Fragment-key share links work the same way: the decryption
key travels in the URL's # fragment, which browsers structurally never send to
any server — so a link-relaying server sees ciphertext too, even for content you're actively
sharing.
Provable, not just promised
Every task change is recorded in a per-device, Ed25519-signed, hash-chained history log — the same construction a tamper-evident audit log or a lightweight blockchain uses. A silent edit, deletion, or backdated timestamp breaks the chain in a way that's detectable, not just against policy. Verify it yourself in the app's "Verify task history" panel.
The frontend itself is verifiable too: every script and stylesheet Haven serves is protected
by Subresource Integrity, with the exact expected hashes published in
integrity.json —
you can independently confirm the code your browser ran matches the code in the public
repository, rather than trusting that it does.
Read the threat model, not just this page
We publish a full threat model — every adversary considered (a malicious or compromised sync server, XSS, a coerced/forced unlock, a future quantum adversary) and exactly what defends against each. It also lists what Haven doesn't protect against today, plainly: record metadata (sizes, timing) isn't hidden from the network or server, and the browser delivering the code is itself a trust boundary — mitigated by the Subresource Integrity mechanism above, not eliminated by it. A privacy pitch that only lists what's protected isn't one you should trust; this is the rest of it.
See it happen in real time
Open the app's own "How your data is protected" panel and watch a task get encrypted as you type it — no separate demo, the real code path.
Open Haven — it's freeHaven's source, including the encryption implementation, is public on GitHub — read it instead of taking this page's word for it.