security model

applies to: all your data

Zero-knowledge by design

Zero-knowledge is an overloaded phrase. Here's exactly what it means in Pock: what the server sees, what it can't see, and what the realistic threats are.

What the server actually holds

When you share a file or store a vault secret with Pock, encryption runs entirely in your browser or CLI before any data leaves your machine. The server receives ciphertext and metadata. It does not receive plaintext or keys. It can tell that a share exists, when it was created, and roughly how large it is. It cannot read the content.

This is the core property: an operator with full database access (or a court order, or a breach) cannot reconstruct your secrets. They'd get encrypted blobs and no decryption material.

The threat model

Threat models should be explicit. Here's what Pock's zero-knowledge design protects against, and what it does not.

Protected

  • Server breach. An attacker who exfiltrates the entire database gets ciphertext. Without your passphrase and your device's Secret Key, they cannot decrypt it.
  • Operator snooping. Pock employees cannot read your secrets. The infrastructure never processes plaintext.
  • Subpoenas. A legal demand for your data produces the same ciphertext the attacker would get. We can hand it over because it's useless without your keys.
  • Harvest-now-decrypt-later. Pock uses post-quantum hybrid encryption. Traffic collected today cannot be decrypted by a future quantum computer. See post-quantum encryption.

Not protected

  • Compromised client. If your browser or machine is compromised before encryption runs, the attacker sees plaintext. Zero-knowledge is a server-side guarantee, not a malware defense.
  • Weak passphrases. Argon2id makes brute-force expensive, but a short passphrase is still attackable given enough time and compute.
  • Metadata. The server knows you created a share, when, and roughly its size. It does not know what's in it.

Two-secret key derivation (2SKD)

Passphrase (memorized) + Secret Key (device-held) derive one key - a breach of either alone is useless.

Standard password-based encryption derives a key from your passphrase alone. If an attacker steals your encrypted vault and knows your passphrase (or brute-forces it), they win.

Pock uses a two-secret derivation: your passphrase is combined with a 128-bit machine-generated Secret Key before Argon2id runs. The Secret Key is stored only on your devices - it is never sent to the server. A server breach produces the Argon2id output hash, which was computed from something the server never had. Brute-force against the database alone is computationally useless.

This is the same model used by 1Password's two-secret derivation. The two secrets live in different trust domains (your memory and your device), so an attacker needs both to get anywhere.

Encryption in practice

The cipher for symmetric encryption is XChaCha20-Poly1305 with a 24-byte random nonce. For multi-recipient or asymmetric cases (like the vault's Account Unlock Key wrapped per unlock method), Pock uses an HPKE-style envelope: KEM encapsulate, HKDF derive, then AEAD encrypt.

The same Rust library (pock-core) runs as a native binary in the CLI and as WebAssembly in the browser, so both surfaces share one audited implementation. See also: Touch ID and WebAuthn PRF, the vault, and secure sharing.

Verification

The source for pock-core is auditable. Pock's browser and CLI builds use the same compiled artifact - there is no server-side decryption path to hide. If you want to verify the claims here, the implementation is the ground truth.

Questions? Read the full docs or the privacy policy.