Security rule #1

Klavox's zero-knowledge architecture, explained

In one sentence: Klavox encrypts and decrypts everything client-side; the server only ever receives, stores and syncs already-encrypted text — never your master password, never your vaultKey, never your entries in the clear.

1. Key derivation

Your master password never leaves your device. It goes through Argon2id (memory ≥ 64 MB, ≥ 3 iterations, parallelism tuned per platform) with your email as salt, producing a 256-bit masterKey.

That masterKey is then stretched by HKDF-SHA256 into two distinct keys: an encryption key (stretchedMasterKey) and an authentication hash (masterPasswordHash) sent to the server — non-reversible, re-hashed server-side before storage.

2. Protected Symmetric Key

A random 256-bit vaultKey is generated at account creation and encrypted with the stretchedMasterKey. The server only stores its encrypted form. Direct consequence: changing the master password only re-encrypts this small key, never the entire vault.

3. Per-entry encryption

Each entry (login, password, notes, TOTP seed, custom fields) is individually encrypted with AEAD — XChaCha20-Poly1305 or AES-256-GCM — using the vaultKey and a unique random nonce per write. A blob's format is version | algo | nonce | ciphertext | tag: AEAD authentication guarantees both confidentiality and integrity. Only minimal sorting metadata (folder, favorite) may stay in the clear — never a URL, login or password.

4. Authentication & session

On login, the client derives and sends masterPasswordHash; the server verifies it (Argon2id of the received hash) and returns a short session token with refresh. 2FA (TOTP/WebAuthn) is offered as an option; local unlock requires the master password on every open, or biometrics that unlock an already-stored key in the keystore/secure enclave.

5. Storage & sync

The server only stores ciphertext and sync metadata (revisions, timestamps, tombstones), on sovereign infrastructure hosted in Europe. Multi-device sync relies on revisions with conflict resolution (last-write-wins per field + journal). An optional recovery key (128 bits, generated at sign-up) is the only safety net if the master password is lost — without it the vault stays unrecoverable: that's the price of real zero-knowledge.

6. One shared crypto core

The crypto core (packages/crypto-core) is written in portable TypeScript, with no network dependency, tested with test vectors and degraded cases (wrong password, invalid tag, replayed nonce). It is used identically by web, Android and iOS: a single audited codebase, not a per-platform reimplementation.

7. Non-negotiable invariants

  • No plaintext secret ever reaches the server, logs, telemetry, a URL or unencrypted storage.
  • Proven primitives only (libsodium / WebCrypto / Argon2id) — never homegrown cryptography.
  • Unique random nonce per encryption; AEAD everywhere.
  • The master password is never stored, transmitted or logged.
  • Every key in memory is wiped as soon as possible.
  • Security review before any use with real credentials.

A question about the architecture?

Write to us — we also answer technical questions before launch.