Back to blog
PolarHQEngineering
EngineeringSecurityDeep dive

How end-to-end encryption works in PolarHQ

by Marques · April 26, 2026

End-to-end encryption is easy to claim and hard to do without making the product miserable to use. The bar we set for PolarHQ: the server stores nothing but ciphertext, and you only ever type one password. No per-file prompts, no key-management homework. Here's how it fits together.

One password, one keypair

When you sign up, your browser does the heavy lifting before anything touches the network:

  1. Generate an X25519 keypair with libsodium.
  2. Derive a key-encryption key (KEK) from your login password using Argon2id.
  3. Wrap (encrypt) your private key with that KEK.
  4. Send the server only { publicKey, wrappedPrivateKey, kdfSalt }.

The server never sees your password, your KEK, or your private key — only an opaque wrapped blob it couldn't open if it wanted to.

password ──Argon2id──▶ KEK ──unwraps──▶ privateKey (memory only)
                                   │
publicKey ──shared──▶ collaborators │

On sign-in, the browser re-derives the KEK, unwraps the private key into memory, and keeps it for the session. That's the only moment your password is in play.

Per-item content keys

Every photo, file, and document gets its own random symmetric content key. The bytes are sealed with crypto_secretbox; the content key itself is wrapped to your public key. To share with someone, we wrap that one content key to their public key — the underlying data never has to be re-encrypted.

This is what lets a single library scale: thousands of items, each independently keyed, all openable with the one private key sitting in your session.

What's encrypted

Short answer: everything that could identify you or your content.

  • Photo and video originals, plus every generated thumbnail
  • Filenames and folder names
  • Document snapshots and the real-time collaboration frames
  • EXIF, captions, and search embeddings

The server sees sizes and timing, and that's roughly it. Even the ML search index — the on-device CLIP embeddings — is encrypted at rest and ranked client-side.

The honest trade-offs

E2E isn't free, and we'd rather be upfront:

  • Lost password = lost data. Without your password there's no KEK, and without the KEK there's no way back in. That's the whole point — but it means a recovery code is essential, and we generate one at signup.
  • No server-side search or rendering of encrypted content. We push that work to the client, which is why search runs in your browser.
  • Sharing is key distribution, not link magic. Public, non-E2E links exist for when you explicitly want them.

The goal isn't encryption for its own sake. It's that nobody — not us, not a cloud provider, not a future acquirer — can read your life without your password.

That's the model. It's the same shape across Photos, Drive, and Docs, and it's why "self-hosted" and "end-to-end encrypted" aren't two features in PolarHQ — they're the same promise.