A zero-knowledge password vault built with Next.js, Supabase Auth, and client-side AES-GCM encryption. All sensitive data is encrypted/decrypted only in the browser using keys derived from your master password.
- 🔐 Zero-Knowledge Architecture: Master password and encryption keys never leave your browser
- 🔒 Client-Side Encryption: AES-GCM encryption with PBKDF2 key derivation
- 🛡️ Row Level Security: Supabase RLS policies ensure data isolation
- 🎨 Modern UI: Clean, responsive interface with dark mode support
- ⚡ Fast & Secure: Built with Next.js 14 App Router
- 📱 Bitwarden-like UX: Familiar interface with lazy reveal and password generator
- Frontend: Next.js 14 (App Router), React, TypeScript, Tailwind CSS
- Backend: Supabase (Auth + Postgres)
- Encryption: Web Crypto API (AES-GCM, PBKDF2-SHA256)
- Hosting: Vercel (Frontend), Supabase (Database)
- Login/Signup → Supabase Auth (email/password)
- Master Password → Enter master password to unlock vault (never sent to server)
- Dashboard → View all vault items with search functionality
- Add/Edit → Create or modify password entries with encryption
- View Item → Bitwarden-like modal with decrypt/reveal functionality
- Settings → Profile, change password, lock vault, logout
npm install- Create a new project at supabase.com
- Go to Project Settings > API to get your URL and anon key
- Run the SQL schema in the Supabase SQL Editor:
- Copy the contents of
supabase/schema.sql - Paste and execute in the SQL Editor
- Copy the contents of
Create a .env.local file in the root directory:
NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
# Optional: PBKDF2 iterations (default: 250000)
NEXT_PUBLIC_PBKDF2_ITERATIONS=250000npm run devOpen http://localhost:3000 in your browser.
- Master Password: User enters master password (never sent to server)
- Key Derivation: PBKDF2-SHA256 with user-specific salt (≥250k iterations)
- Encryption: AES-GCM with 96-bit random IV per field
- Storage: Encrypted data stored as
ivB64:ctB64base64 strings
- Encrypted:
entry_username,entry_password(AES-GCM) - Plaintext:
entry_name,entry_url,folder(metadata only) - Settings:
kdf_salt,kdf_itersstored invault_settingstable
- ✅ Row Level Security (RLS) on all tables
- ✅ Client-side only encryption/decryption
- ✅ Master password never transmitted
- ✅ Encryption keys only in runtime memory
- ✅ Lazy reveal for sensitive fields
- ✅ Session-based vault unlock (sessionStorage flag only)
├── app/
│ ├── dashboard/ # Main vault pages
│ │ ├── page.tsx # Dashboard (all items)
│ │ ├── new/ # Add new password
│ │ ├── view/[id]/ # View item modal
│ │ └── edit/[id]/ # Edit item
│ ├── login/ # Login page
│ ├── signup/ # Signup page
│ ├── settings/ # Settings page
│ └── layout.tsx # Root layout
├── components/
│ ├── sidebar.tsx # Navigation sidebar
│ ├── vault-item-card.tsx
│ ├── vault-form.tsx
│ ├── password-generator.tsx
│ └── master-password-prompt.tsx
├── lib/
│ ├── crypto/ # Encryption utilities
│ ├── contexts/ # React contexts (KeyProvider)
│ └── supabase/ # Supabase clients
├── supabase/
│ └── schema.sql # Database schema
└── middleware.ts # Auth middleware
/- Redirects to login or dashboard/login- Supabase Auth login/signup- Supabase Auth signup/dashboard- Main vault dashboard (requires master password)/dashboard/new- Add new password entry/dashboard/view/[id]- View item details (Bitwarden-like modal)/dashboard/edit/[id]- Edit item/settings- User settings (profile, change password, lock vault)
- Push your code to GitHub
- Import project in Vercel
- Add environment variables in Vercel dashboard
- Deploy!
Make sure to set the same environment variables in your Vercel project settings.
# Development server
npm run dev
# Build for production
npm run build
# Start production server
npm start
# Lint
npm run lintThe application uses the following crypto functions:
makeSaltB64(len)- Generate random salt as base64deriveKey(master, saltB64, iters)- Derive AES-GCM key via PBKDF2encryptString(key, plaintext)- Encrypt string, returnsivB64:ctB64decryptString(key, packed)- DecryptivB64:ctB64string
MIT