https://github.com/bastipnt/passmgr
Zero-knowledge password manager — cross-platform web + mobile, TypeScript monorepo. Early prototype.
https://github.com/bastipnt/passmgr
bun cryptography drizzle-orm e2ee end-to-end-encryption expo fastify monorepo opaque pake password-manager react react-native self-hosted tailwindcss trpc turborepo typescript zero-knowledge
Last synced: about 6 hours ago
JSON representation
Zero-knowledge password manager — cross-platform web + mobile, TypeScript monorepo. Early prototype.
- Host: GitHub
- URL: https://github.com/bastipnt/passmgr
- Owner: bastipnt
- License: other
- Created: 2025-12-01T11:23:15.000Z (7 months ago)
- Default Branch: main
- Last Pushed: 2026-06-16T09:42:50.000Z (9 days ago)
- Last Synced: 2026-06-16T11:23:15.159Z (9 days ago)
- Topics: bun, cryptography, drizzle-orm, e2ee, end-to-end-encryption, expo, fastify, monorepo, opaque, pake, password-manager, react, react-native, self-hosted, tailwindcss, trpc, turborepo, typescript, zero-knowledge
- Language: TypeScript
- Homepage:
- Size: 3.32 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Security: SECURITY.md
- Agents: AGENTS.md
Awesome Lists containing this project
README
# passmgr
A full-stack, cross-platform password manager built on **OPAQUE** zero-knowledge authentication. TypeScript monorepo, pnpm + Turborepo.
[](./LICENSE)
> ⚠️ **Early prototype — not production-ready.**
>
> The cryptographic stack has not been audited. The architecture, API, and storage format change frequently. **Do not store real passwords with this yet.** Treat this as a research / learning project that happens to compile.
## What it is
A password manager that uses [OPAQUE](https://datatracker.ietf.org/doc/draft-irtf-cfrg-opaque/) (an asymmetric PAKE) so the server never sees your plaintext password — not at registration, not at login, not even in transit. The vault key is wrapped client-side and stored encrypted on the server.
### Key hierarchy
```
password ──Argon2id──► passwordKEK ──encrypt──► vaultKey
recoveryKey ──HKDF──► recoveryKEK ──encrypt──► vaultKey (backup wrap)
sessionKey ──HKDF──► sessionSecret ──HKDF(+salt)──► authKey (HMAC request signing)
```
Email is stored encrypted (XChaCha20-Poly1305) and indexed via a server-keyed HMAC — never as plaintext.
## What works today
- **Web client**: registration, login, vault list / view / add / edit / delete, real-time record sync.
- **Server**: OPAQUE flow end to end, HMAC-signed request auth, session storage in Redis, replay protection (5 min timestamp window).
- **Tests**: Vitest unit + integration suites, Playwright E2E for register/login, Stryker mutation testing on crypto / store / server-auth / client packages.
## What's missing
- **Web**: no idle lock, no password recovery UI, no auto-relock on tab close.
- **Mobile**: auth flow only. No vault, no records, no biometric unlock yet.
- **Server**: no rate limiting, some signature-validation edge cases still TODO.
See [roadmap.md](./roadmap.md) for the full plan.
## Stack
| Layer | Tech |
| ------- | --------------------------------------------------------------------- |
| Web | React 19, Vite (rolldown-vite), Tailwind v4, wouter, tRPC client |
| Mobile | React Native 0.83, Expo 55, Tamagui, NativeWind |
| Server | Fastify 5, tRPC 11, Bun runtime, Drizzle ORM (1.0 beta) |
| Data | PostgreSQL 17, Redis 7 |
| Crypto | `@cloudflare/opaque-ts`, `@noble/hashes`, `@noble/ciphers` |
| Tooling | pnpm 10 workspaces, Turborepo, OXLint, Prettier, Lefthook, commitlint |
## Repo layout
```
apps/
web/ React 19 + Vite web client
mobile/ React Native + Expo client (auth-only for now)
server/ Fastify + tRPC backend, runs on Bun
packages/
client/ Shared React hooks (useLogin, useRegistration) + tRPC client + secrets store
crypto/ All cryptographic primitives
db/ Drizzle schema + migrations (PostgreSQL)
schema/ Zod schemas shared between client and server
store/ Frontend data store + sync logic
tokens/ Design tokens (colors, spacing)
types/ Shared TypeScript types
typescript-config/ Shared tsconfig base files
ui/ Shared web component library (shadcn-based)
ui-native/ Mobile component library (Tamagui-based)
util/ Base64 / string encoding helpers
```
## Quick start
You need: Node 18+, pnpm 10, Docker (for Postgres + Redis), and optionally Bun (server runtime).
```bash
pnpm install
# Start Postgres + Redis
pnpm db:up
# Run migrations
pnpm db:migrate
# Start everything in watch mode
pnpm dev
```
### Required env vars
Server (`apps/server/.env`):
| Var | Notes |
| --------------------- | ---------------------------------------------------------------------------------- |
| `DATABASE_URL` | PostgreSQL connection string |
| `REDIS_HOST` | e.g. `localhost` |
| `REDIS_PORT` | e.g. `6379` |
| `OPAQUE_SERVER_SETUP` | base64 OPAQUE server setup. **Must stay stable** — rotating invalidates all users. |
DB package (`packages/db/.env`):
| Var | Notes |
| -------------- | ------------------------------ |
| `DATABASE_URL` | Same as above, used by Drizzle |
### Common scripts
```bash
pnpm dev # all apps in watch mode
pnpm build # build everything via turbo
pnpm lint # OXLint, type-aware
pnpm typecheck # tsc across the monorepo
pnpm test # Vitest unit tests
pnpm test:integration # integration suites
pnpm e2e # Playwright
pnpm format # Prettier
pnpm db:generate # Drizzle migration generation
pnpm db:migrate # Drizzle migration apply
```
Per-app:
```bash
pnpm --filter web dev
pnpm --filter server dev
pnpm --filter mobile start
```
## Per-app docs
- [apps/web/README.md](./apps/web/README.md)
- [apps/mobile/README.md](./apps/mobile/README.md)
- [apps/server/README.md](./apps/server/README.md)
## Contributing
PRs welcome — see [CONTRIBUTING.md](./CONTRIBUTING.md). Open an issue before tackling anything large; the architecture is still in motion.
## Security
**Do not file public issues for security problems.** See [SECURITY.md](./SECURITY.md) for the private disclosure path.
The crypto stack is **unaudited**.
## License
[AGPL-3.0-only](./LICENSE). You can self-host and modify freely; if you run a modified version as a network service, you must publish your source under the same license.