{"id":50615003,"url":"https://github.com/dris1153/zk-vault","last_synced_at":"2026-06-06T07:30:21.234Z","repository":{"id":362756669,"uuid":"1260056615","full_name":"dris1153/zk-vault","owner":"dris1153","description":"Zero-knowledge personal credential vault — client-side Argon2id + AES-256-GCM encryption, the server stores only ciphertext. WebAuthn unlock, TOTP, PWA. Next.js + Supabase.","archived":false,"fork":false,"pushed_at":"2026-06-05T18:56:07.000Z","size":629,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"dev","last_synced_at":"2026-06-05T20:12:10.543Z","etag":null,"topics":["2fa","aes-256-gcm","argon2","bip39","client-side-encryption","credential-vault","e2ee","end-to-end-encryption","nextjs","passkey","password-manager","pwa","self-hosted","supabase","tailwindcss","totp","typescript","web-crypto-api","webauthn","zero-knowledge"],"latest_commit_sha":null,"homepage":"https://security.drisdev.io","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dris1153.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"docs/security-model.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-05T05:46:11.000Z","updated_at":"2026-06-05T18:51:10.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dris1153/zk-vault","commit_stats":null,"previous_names":["dris1153/zk-vault"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/dris1153/zk-vault","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dris1153%2Fzk-vault","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dris1153%2Fzk-vault/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dris1153%2Fzk-vault/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dris1153%2Fzk-vault/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dris1153","download_url":"https://codeload.github.com/dris1153/zk-vault/tar.gz/refs/heads/dev","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dris1153%2Fzk-vault/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33973868,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-06T02:00:07.033Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["2fa","aes-256-gcm","argon2","bip39","client-side-encryption","credential-vault","e2ee","end-to-end-encryption","nextjs","passkey","password-manager","pwa","self-hosted","supabase","tailwindcss","totp","typescript","web-crypto-api","webauthn","zero-knowledge"],"created_at":"2026-06-06T07:30:19.004Z","updated_at":"2026-06-06T07:30:21.208Z","avatar_url":"https://github.com/dris1153.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Vault - Personal Zero-Knowledge Credential Vault\n\nA single-user, end-to-end encrypted store for logins, wallet keys, seed phrases,\nSSH keys, secure notes, and API keys. All encryption happens in your browser;\nSupabase only ever stores ciphertext.\n\nBuilt with Next.js (App Router) + Supabase (Postgres + Auth + RLS) + Tailwind v4.\n\n## Security model (read this)\n\n- **Zero-knowledge.** Your master password never leaves the browser. Encryption\n  and decryption happen client-side only - no plaintext passes through any\n  server route or action (enforced by `npm run guard`).\n- **Envelope encryption.** A random 256-bit Data Encryption Key (DEK) encrypts\n  every item (AES-256-GCM). The DEK is wrapped by a key derived from your master\n  password (Argon2id) and, separately, by a key from your 24-word recovery key.\n- **Email-derived auth salt.** Your Supabase login secret is\n  `Argon2id(master, salt = SHA-256(email))` with a fixed cost, so you can log in\n  from any device with just master + email - no server read needed first.\n- **Strict RLS.** Every row is scoped to `auth.uid()`. Even with the public anon\n  key, rows are unreadable without your login and contain only ciphertext.\n- **No \"forgot password\".** If you lose your master password, recover with your\n  24-word recovery key + your encrypted `.vault` backup (Settings -\u003e Backup).\n  Lose both and the data is unrecoverable - that is the cost of zero-knowledge.\n- **Residual risks (honest):** a web app re-downloads its crypto code on each\n  load, so a compromised host/dependency could serve malicious JS. Mitigated by\n  CSP, pinned deps, and self-hosting; not fully solvable for web vaults. A\n  compromised device (keylogger/malware) is also out of scope. See\n  `docs/security-model.md`.\n\n## Setup\n\n1. **Supabase:** create a project, copy the URL + anon key.\n2. **Env:** `cp .env.local.example .env.local` and fill `NEXT_PUBLIC_SUPABASE_URL`,\n   `NEXT_PUBLIC_SUPABASE_ANON_KEY`. For `npm run db:reset` also set `SUPABASE_DB_URL`\n   (session-pooler connection string). See `supabase/README.md`. The vault email is\n   entered on the lock screen at first signup/unlock, not via env.\n3. **Auth:** in Supabase, turn OFF \"Confirm email\".\n4. **Schema:** apply `supabase/migrations/0001_init.sql` (SQL Editor, or\n   `npm run db:reset`).\n5. **Verify:** `npm run verify:supabase you@gmail.com` (live end-to-end smoke test).\n6. **Run:** `npm run dev` -\u003e http://localhost:3000 -\u003e create your vault.\n\n## Scripts\n\n| Script                            | Purpose                                                        |\n| --------------------------------- | -------------------------------------------------------------- |\n| `npm run dev` / `build` / `start` | Next.js dev / production build / serve                         |\n| `npm test`                        | Crypto unit tests (Vitest)                                     |\n| `npm run typecheck`               | `tsc --noEmit`                                                 |\n| `npm run guard`                   | Fail if any server-context file imports the crypto/vault layer |\n| `npm run verify:supabase`         | Live engine smoke test (throwaway account)                     |\n| `npm run db:reset`                | Drop + re-apply migrations (DEV ONLY - wipes vault data)       |\n\n`npm run build` runs the guard first.\n\n## Architecture\n\n```\nlib/crypto/     pure, framework-agnostic crypto (KDF, AES-GCM, envelope, recovery)\nlib/supabase/   browser client, auth, vault_config, provisioning (ciphertext I/O)\nlib/vault/      session (RAM DEK), unlock/lock, CRUD, search, export/import, settings\nlib/ui/         icon map, clipboard hook, field config\ncomponents/     lock screen, app shell, sidebar, cards, drawer, modals, settings\napp/            App Router shell + page orchestrator\nsupabase/       migration + setup guide\nscripts/        verify, db-reset, zero-knowledge guard\n```\n\nDesign system: `DESIGN.md` (Electric Azure on Obsidian, dark-only).\nImplementation plan + history: `plans/260605-1204-zk-credential-vault/`.\n\nIn-app user guide (Vietnamese, with diagrams): the **`/docs`** route - storage\nworkflow, unlock flow, deployment A-Z, recovery, and FAQ. This README is the\nEnglish dev reference; `/docs` is the canonical user-facing guide.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdris1153%2Fzk-vault","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdris1153%2Fzk-vault","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdris1153%2Fzk-vault/lists"}