
Zero Locker
A self-hosted, open-source password manager built with Next.js 15, TypeScript, Prisma, and Neon Postgres — encrypting credentials, payment cards, and secrets with AES-256-GCM behind a type-safe oRPC API and BetterAuth authentication.
🔐 Zero Locker — A Self-Hosted, Open-Source Password Manager
Zero Locker is a self-hosted, open-source password management solution I built to give people full control over their credentials, payment cards, and secrets without trusting a third-party vault. The entire codebase — server, database schema, and encryption logic — is public on GitHub, so anyone can audit exactly how their data is handled instead of taking a vendor's word for it.
🌟 The Problem
Most password managers ask you to trust a closed-source, cloud-hosted vault with your most sensitive data. I wanted an option that was:
- Auditable — open-source, so the encryption and storage logic can be inspected line by line
- Self-hostable — runs on your own infrastructure instead of a vendor's servers
- Not just passwords — credentials, payment cards, and arbitrary secrets (API keys, SSH keys, tokens) in one place
- Modern to use — a fast, well-designed dashboard rather than a dated enterprise UI
✨ Core Features
Straight from the project's own feature set:
- End-to-end encryption — AES-256-GCM for all sensitive fields
- Credential storage — usernames, passwords, and per-credential metadata (recovery email, phone number, whether 2FA is enabled)
- Payment card management — card number and CVV stored encrypted, alongside card metadata like credit limit, rewards program, and contactless/international payment flags
- Secret storage — typed secrets (API keys, database URLs, SSH keys, JWT secrets, OAuth tokens, webhook secrets, general tokens) with expiry tracking
- Containers — group credentials, cards, and secrets into folders; a container can be restricted to a single entity type, including a secrets-only mode built for exporting environment variables
- Platforms — credentials are linked to a platform (e.g. a specific service), with a review workflow (approved/pending/rejected) for platforms submitted by users
- Password history — automatic tracking of credential changes over time
- Tagging — custom tags across credentials, cards, and secrets
- Authentication — session and account management via BetterAuth
- Dark/light theme, responsive UI — built with Tailwind CSS and shadcn/ui
- Self-hosted deployment — Docker Compose for a local PostgreSQL instance, with the app itself deployable to Vercel or any Node host
🏗️ Technical Architecture
Data Model
The schema is split into focused Prisma files rather than one monolith — credential.prisma, cards.prisma, secrets.prisma, encryption.prisma, auth.prisma — and centers on a few real design decisions:
Credential,Card, andSecretare separate models, each with their own metadata model (CredentialMetadata,CardMetadata,SecretMetadata) rather than one generic "item" table — so a card can carry a credit limit and rewards program while a secret carries a type and expiry date, without either model being forced into a shape it doesn't need.EncryptedDatais a shared table (iv,encryptedValue,encryptionKey) referenced by every sensitive field — a credential's password, a card's number and CVV, and a secret's value all point to their ownEncryptedDatarow, so encryption is handled uniformly across entity types instead of being reimplemented per field.Containergroups items into folders, with aContainerType(MIXED,SECRETS_ONLY,CREDENTIALS_ONLY,CARDS_ONLY) — a secrets-only container is what backs environment-variable-style operations.Platformties a credential to the service it belongs to, with its own approval workflow (APPROVED/PENDING/REJECTED) for platforms added by users rather than pre-seeded.UserPlandistinguishesNORMALaccounts (limited to 3 default containers) fromPROaccounts (unlimited containers).
Tech Stack
- Next.js 15 (App Router, Turbopack dev server) and React 19
- TypeScript throughout, validated at the boundaries with Zod
- Prisma ORM 6 over Neon serverless Postgres (
@prisma/adapter-neon) - oRPC for a type-safe, contract-first API layer between client and server (
@orpc/server,@orpc/client,@orpc/react-query) - BetterAuth for session and account authentication
- TanStack Query for client-side data fetching and caching
- Tailwind CSS and shadcn/ui (Radix primitives) for the interface
- Resend for transactional email, Vercel Analytics for usage metrics
Security
- AES-256-GCM encryption applied to every sensitive field before it's written to the database — credential passwords, card numbers and CVVs, and secret values
- Each encrypted value gets its own record in the shared
EncryptedDatatable with a unique initialization vector, so encryption isn't reused across fields or users - Credential password changes are tracked in a separate
CredentialHistorymodel, itself encrypted the same way as the live value
🚀 Self-Hosting
Zero Locker is designed to be run on your own infrastructure:
git clone https://github.com/FindMalek/zero-locker.git
cd zero-locker
pnpm install
cp .env.example .env # set DATABASE_URL, BETTER_AUTH_SECRET, etc.
pnpm docker:up # starts a local PostgreSQL 15 container
pnpm db:migrate # applies the Prisma schema
pnpm dev # starts the Next.js dev server on :3000
The included docker-compose.yml handles local Postgres, and the same Prisma schema runs against Neon in production. Project scripts also cover day-to-day operations — docker:status, docker:logs, docker:reset, db:reset-and-seed — for resetting or inspecting the local database during development.
📌 Where It Stands
Zero Locker is open-source, MIT-licensed, and live at zero-locker.com. The codebase is primarily TypeScript, with the full schema, oRPC routers, and UI available for anyone to read, run, or contribute to on GitHub — issues and pull requests are open.