In an age where personal data breaches have become all too common, a radical shift in the way we store and manage sensitive information is not just overdue—it's essential. Password managers are indispensable tools in today’s digital lifestyle, but they’re also prime targets for attackers. What if we could build one that even we—the developers—couldn’t spy on?
Welcome to the world of Zero-Knowledge Password Managers. This post explores the architecture behind building one using Next.js and Supabase, combining modern frontend tooling with secure client-side cryptography and cloud database services. We’ll walk through the theory, practical implementation strategy, and the philosophy that makes zero-knowledge systems so important today.
Understanding Zero-Knowledge in Context
Zero-knowledge (ZK) doesn’t necessarily refer to complex cryptographic proofs in this context. Instead, it embodies a simple but powerful idea: don’t store or transmit anything that you don’t absolutely need to. In the case of a password manager, that means never storing plaintext passwords, nor the encryption keys that could unlock them.
Even if the server gets hacked, the attackers get... nothing useful. Why? Because all sensitive operations—encryption and decryption—are performed entirely on the client. The server sees only encrypted blobs.
Think of it this way: you don’t give your diary to the cloud and ask it to keep your secrets safe. You keep the key, and the cloud stores a locked box.
Architectural Overview
We’re using Next.js to handle both the frontend and API routes, and Supabase to manage authentication and database storage.
[User]
↕️ Sign Up/Login, Create, Retrieve
↕️ [Client-Side Encryption/Decryption Layer (in-browser)]
↕️ Encrypted Vault Data [Next.js Frontend + API Routes] ↔ [Supabase: Auth & PostgreSQL DB]
Key Idea:
Only encrypted data ever reaches Supabase. Decryption is only possible with the key derived from the user's master password—held solely in the browser’s memory.
Component Deep Dive
1. Client-Side Encryption
Encryption starts where it should: at the user’s fingertips. When users create or access a vault, the app:
- Derives an encryption key from the master password using a KDF (Key Derivation Function) like Argon2id or PBKDF2.
- Encrypts the vault content using AES-GCM or XChaCha20-Poly1305.
- Sends the encrypted blob (plus IV and metadata) to Supabase.
This key never leaves the browser. No plaintext ever touches your backend.
2. User Authentication
There are two broad approaches:
Option A: Supabase Auth + Master Password
- Supabase handles session and identity management.
- Upon login, the app prompts the user for their master password to decrypt vaults.
Option B: Secure Remote Password (SRP)
- A more zero-knowledge-pure option.
- Passwords are never stored or transmitted.
- Login is a cryptographic dance between client and server.
For simplicity and compatibility, most teams begin with Option A.
3. Vault Data Schema
A simplified vault structure might look like:
Field | Type | Description |
---|
user_id | UUID | Supabase user ID |
vault_name | Text | Encrypted vault title |
data | Text/Blob | Encrypted password entry blob |
iv | Text | Initialization vector |
created_at | Timestamp | Record creation timestamp |
Every entry is encrypted individually for improved forward secrecy.
Full Lifecycle Flow
Sign Up
- User signs up via Supabase Auth.
- App asks user for a master password.
- Master password is used to derive the encryption key (via KDF).
- The key is stored only in volatile memory (not localStorage).
Login & Unlock
- User logs in to Supabase.
- App prompts for the master password.
- Vaults are fetched and decrypted in the browser.
Add or Edit Vault
- New credentials are entered by the user.
- Data is encrypted with the master key.
- Encrypted blob + IV sent to Supabase.
View or Retrieve
- Encrypted vaults are queried from Supabase.
- App uses the derived key to decrypt.
- Data is shown to user; key remains in memory only.
Logout or Timeout
- Clear the key from memory.
- Re-lock the vault until the master password is entered again.
Security Features & Design Philosophy
- Client-side encryption means no sensitive plaintext ever leaves the browser.
- Key derivation using slow, secure algorithms prevents brute-force attacks.
- IV reuse prevention ensures uniqueness for each encryption operation.
- No key = no data. Even developers with full DB access see only encrypted gibberish.
The philosophy is simple: trust the user, not the server.
Advanced Enhancements
Key Rotation
Let users change their master password without data loss:
- Decrypt all entries with old key.
- Re-encrypt with new key.
- Upload updated blobs.
Searchable Encryption (Advanced)
For large vaults:
- Implement order-preserving or searchable symmetric encryption.
- Enables search without full decryption.
Encrypted Metadata
Even vault names can be encrypted for full ZK compliance.
Secret Recovery Options
- Use secret-sharing (e.g., Shamir’s) for backup.
- Allow recovery via emergency contact with secure multi-party confirmation.
Why This Matters
The Zero-Knowledge model shifts the burden of trust. In traditional systems, trust lies in the server’s ability to protect your data. In ZK systems, trust lies in cryptographic guarantees.
As we step into a world increasingly conscious of surveillance, privacy, and control, ZK architectures empower users to own their data. And as developers, we remove ourselves from the risk and liability of sensitive data handling.
Final Thoughts
Building a zero-knowledge password manager is both a technical and philosophical challenge. But with tools like Next.js and Supabase, the barrier to entry is lower than ever.
You don’t need to be a cryptographer to get started—you just need to be willing to rethink traditional trust models.
Let’s build software where even we don’t hold the keys.
Interested in building your own zero-knowledge app? Follow for more technical deep dives and architectural breakdowns.