security

I can't read your notebook. Here's why.

Most apps say "encrypted" and hope you don't ask who holds the key. Here's the whole answer, in plain language — including the parts that aren't perfect.

The short version

Everything you write — the page, the cabinet, your tasks, every shelved book — is encrypted on your device before it's sent. The key that opens it is made on your device and never leaves it. My servers store ciphertext, a few salts, and some wrapped blobs. None of it opens without a key I don't have. It's not a promise to be careful. It's an architecture.

How the key works

Your master key

When you first open 48pages, your device generates a master key — 32 random bytes. It is not derived from your password, not recoverable from anything on my side, and it never touches the network. Every byte of your writing is encrypted under it with AES-256-GCM.

Three ways in, one key

You need to be able to unlock the notebook without shipping that master key anywhere. So the master key is wrapped — encrypted again — under each credential you set up, any one of which can open it:

  • Your passphrase, stretched with Argon2id (64 MiB, deliberately slow) so a stolen blob can't be brute-forced.
  • Your recovery phrase — the root credential, unresettable. It's the one thing that can always get you back in, which is exactly why I can't reset it for you.
  • A passkey (Touch ID / Face ID), via the WebAuthn PRF extension — the authenticator itself produces the secret that unwraps the key, so a look at your face does what a passphrase does, faster.

Unlocking is not logging in

Each credential is split, by HKDF domain separation, into two independent secrets: one that unwraps your master key (never sent) and one auth key that proves to the server you're allowed to fetch your ciphertext. The server only ever stores the SHA-256 of that auth key — so even the thing I use to log you in isn't the thing that opens your notebook.

What the server actually holds

Ciphertext, salts, wrap blobs, and auth-key hashes. That's the entire list. There is no column, anywhere, that contains a word you wrote or a key that could reveal one.

Search stays on your device

Because I can't read your notebook, I can't index it either. Search runs locally, over content your device has already decrypted. The server never sees a query and never builds an index. It's a real constraint, and I'd rather have it than the alternative.

Where I'm honest about the edges

The tool shouldn't pretend. A few things are worth saying out loud:

  • Your recovery phrase is unrecoverable — by design. If you lose it and your other credentials, your notebook is gone, and I can't get it back. The same math that keeps me out keeps me from helping here. Write the phrase down somewhere real.
  • I trust your browser. Encryption happens in the browser, so a compromised device, a hostile extension, or malware is outside what I can protect against. That's true of every browser-based encrypted tool; I'd rather name it than imply otherwise.
  • Passkeys on Firefox. Firefox doesn't broadly ship the PRF extension yet, so on Firefox you get the security of passkey auth but not one-tap biometric unlock — it falls back to your passphrase. An honest tax to flag.
  • No third-party audit yet. I'll pay for one when there are paying users to justify it. Until then, the crypto is small, self-contained, and readable — and the test suite exists to make the claims on this page true, not just stated.

telemetry: none · this page is the proof.