Low Level Design: Password Manager

A password manager is security-critical software. Every design decision either exposes user secrets or protects them. The central architectural constraint is zero-knowledge: the server must never see plaintext passwords or vault contents.

Zero-Knowledge Architecture

Zero-knowledge means all encryption and decryption happens on the client. The server stores only ciphertext it cannot read. Even if the server is fully compromised, user passwords remain safe. Authentication to the server is handled separately from vault decryption — knowing your account credentials does not give the server the key to your vault.

Master Password and Key Derivation

The master password is never stored anywhere. Instead it is passed through a key derivation function (KDF) to produce the encryption key. Use PBKDF2-SHA256 or Argon2id. Argon2id is preferred for new systems — it is memory-hard, which makes GPU-based brute-force expensive.

Key derivation inputs: master password + user-specific salt (stored on server, not secret). Output: a 256-bit symmetric key used to encrypt the vault. The salt prevents precomputed rainbow table attacks across accounts.

For server authentication, derive a separate authentication key from the master password using a different salt or domain separation string. Never reuse the encryption key for authentication.

Vault Encryption

Vault items are encrypted with AES-256-GCM. GCM provides both confidentiality and integrity — tampering with ciphertext produces an authentication failure on decryption, not corrupted data.

Each item gets a unique IV (initialization vector). Never reuse an IV with the same key. Generate IVs with a cryptographically secure random number generator.

Item Storage Schema

Server-side table for vault items:

vault_items
  id            UUID, primary key
  user_id       UUID, foreign key
  type          ENUM('login','note','card','identity')
  encrypted_payload  BLOB  -- AES-256-GCM ciphertext
  iv            BINARY(12)
  updated_at    TIMESTAMP
  deleted       BOOLEAN

The server sees only the type enum and timestamps. The payload — URL, username, password, notes — is opaque ciphertext. Soft deletes (deleted flag) allow sync to propagate removals without losing history.

Sync Protocol

Sync is client-initiated. On connect, the client sends its last-sync timestamp. The server returns all items with updated_at greater than that timestamp. The client decrypts each item locally and merges into its local store using last-write-wins on updated_at.

Conflict resolution: if two devices edit the same item offline, the one with the later updated_at wins. For safety, keep the losing version as a revision so the user can recover it. All merge logic runs on the client against encrypted blobs — the server just stores and serves them.

Autofill Browser Extension

The browser extension communicates with a local companion app (native messaging) that holds the unlocked vault in memory. The extension reads the current page origin, queries the companion for matching login items, and injects credentials into form fields.

Match logic: normalize the page URL to its eTLD+1 (e.g., accounts.google.com → google.com) and compare against stored URL patterns. Substring matching on domain, not full URL, to handle login subdomains.

Breach Detection via k-Anonymity

To check whether a stored password appears in known breach dumps, use the HaveIBeenPwned Pwned Passwords API with k-anonymity. The client hashes the password with SHA-1, sends the first 5 hex characters to the API, and receives back all hashes that share that prefix. The client then checks locally whether its full hash is in the response. The server never learns the full hash of any password.

Sharing Between Users

Sharing a vault item with another user requires asymmetric encryption. Each user has an RSA or EC key pair; the public key is stored on the server. To share an item, the sender re-encrypts the item symmetric key with the recipient public key and sends the wrapped key to the server along with the ciphertext. The recipient decrypts the wrapped key with their private key, then decrypts the item. The server never has access to either key.

Key Points

  • Zero-knowledge: all encryption client-side, server stores only ciphertext
  • Master password → Argon2id → AES-256-GCM vault key, never stored
  • Unique IV per item, stored alongside ciphertext
  • Sync: last-write-wins on updated_at, client-side merge
  • Breach check: k-anonymity prefix query, no full hash sent to server
  • Sharing: asymmetric key wrapping, recipient decrypts with private key

FAQ: Password Manager

What is a zero-knowledge password manager architecture?

A zero-knowledge architecture means the server never has access to unencrypted user data. All encryption and decryption happens client-side using a key derived from the master password. The server stores only ciphertext and cannot read vault contents even if compromised. The service provider has zero knowledge of the plaintext passwords stored by users.

How does master password-based encryption work (PBKDF2/Argon2)?

The master password is never stored directly. Instead, a key derivation function (KDF) such as PBKDF2 or Argon2 stretches the master password into a strong cryptographic key using a salt. PBKDF2 applies HMAC-SHA256 many thousands of times to increase brute-force cost. Argon2 is memory-hard, making GPU attacks expensive. The derived key encrypts the vault with AES-256. A separate authentication hash is sent to the server for login verification, keeping the encryption key entirely client-side.

How do you sync vault data across devices without the server seeing plaintext?

The vault is encrypted on the client before being uploaded. Each device downloads the ciphertext and decrypts it locally using the master-password-derived key. Sync conflicts are resolved using timestamps or vector clocks on encrypted blobs. The server acts as a dumb storage layer — it stores, versions, and serves opaque encrypted payloads without any ability to inspect their contents.

How does breach detection work using k-anonymity?

To check whether a password appears in a breach database without revealing it to the server, the client hashes the password with SHA-1, sends only the first 5 characters of the hash to the API, and receives back all hashes sharing that prefix. The client then checks locally whether the full hash is in the returned list. This k-anonymity model means the server never learns which specific password was queried, preserving user privacy while enabling breach detection.

See also: Netflix Interview Guide 2026: Streaming Architecture, Recommendation Systems, and Engineering Excellence

See also: Atlassian Interview Guide

See also: Scale AI Interview Guide 2026: Data Infrastructure, RLHF Pipelines, and ML Engineering

Scroll to Top