"Your passwords, SSH keys, and secrets — encrypted, local, and actually yours."
Screenshots · Install · Features · How it works · Development
VaultKeep is a local password manager for Ubuntu desktop. No cloud, no account, no telemetry — every entry lives in a single AES-256-GCM encrypted file on your own disk. It stores website logins, SSH credentials, and secure notes, with a password generator, TOTP codes, one-tap SSH command copy, and an optional Face ID quick-unlock from your iPhone over your home network.
- 🔒 Local, encrypted vault — AES-256-GCM with a scrypt-derived key. Your master password is never stored anywhere and can't be recovered if you forget it — that's the point.
- 🗂️ Three entry types — Logins, SSH credentials, and secure notes, each with tags, favorites, and free-form custom fields for anything else (API keys, recovery codes…).
- 🎲 Password generator — length, character sets, ambiguous-character exclusion, live strength meter.
- 🔑 TOTP codes — paste a setup key or
otpauth://URI once, get a live 6-digit code with a countdown, right on the entry. - 📋 Clipboard auto-clear — copied secrets wipe themselves from the clipboard after a configurable timeout.
- ⏱️ Inactivity auto-lock — locks itself after idle time; quick-resume without a full re-decrypt.
- 🔢 Quick-unlock PIN — reopen a locked session with a short PIN instead of retyping a long master password. Works offline, on any network. Five wrong guesses purge the session key and force a full master-password unlock.
- 📤 Encrypted import/export — back up to a
.pmvaultfile (e.g. a USB drive) and restore it anywhere. - 📱 iPhone Face ID unlock (optional, experimental) — scan a QR code, approve with Face ID, resume the session. A real local WebAuthn ceremony over your LAN, not a gimmick — but it needs both devices on a network that permits local discovery, so it won't work on many company or public Wi-Fi networks. Treat the PIN as the dependable option and this as a bonus. See How it works.
- 🖥️ Native Linux packaging — ships as
.deband.AppImage.
Grab the latest release from the Releases page:
# .deb (installs into the system app menu)
sudo dpkg -i vaultkeep_<version>_amd64.deb
# or AppImage (no installation needed)
chmod +x VaultKeep-<version>.AppImage
./VaultKeep-<version>.AppImageFirewall note: the optional iPhone Face ID feature runs a small local server on your machine (ports
8787/8788, LAN-only). If you use it and haveufwenabled:sudo ufw allow from <your-subnet>/24 to any port 8787:8788 proto tcp comment 'VaultKeep iPhone unlock'
git clone https://github.com/MUHAMMEDHAFEEZ/vaultkeep.git
cd vaultkeep
npm install
npm run dev # run in development
npm run build # produce .deb + .AppImage in release/┌─────────────────────┐ IPC (typed, validated) ┌──────────────────────────┐
│ Renderer (React) │ ───────────────────────────────────▶ │ Main process (Node) │
│ zero Node access │ ◀─────────────────────────────────── │ crypto · vault · files │
└─────────────────────┘ preload (contextBridge) └──────────────────────────┘
- Encryption —
scrypt(masterPassword, salt) → key, thenAES-256-GCMover the whole vault payload. The envelope is versioned JSON; the GCM auth tag is the "wrong password" check — no separate verifier is stored. - Process isolation — the renderer never touches the filesystem or crypto directly.
contextIsolation+sandboxare on; the preload script exposes a narrow, typedwindow.apisurface. Every IPC payload is validated withzodon the main side. - Quick-unlock PIN — verified in the main process against a scrypt hash stored
inside the encrypted vault payload (never in
Settings, which is sent to the renderer). A short PIN is brute-forceable by construction, so the actual control is the attempt limit: five wrong guesses zero the session key and demand the master password. It gates a session whose key is already in memory — it never derives the vault key. - Face ID unlock — an optional, self-signed local HTTPS server (backed by a
per-machine CA you install once) runs a real WebAuthn
registration/authentication ceremony against your iPhone's Safari + Secure Enclave.
Same trust model as the PIN: a quick-resume mechanism for an already-unlocked
session, not a replacement for the master password, and no stronger than "whoever can
see your screen." Because WebAuthn binds credentials to a hostname, this relies on
mDNS (
<hostname>.local) resolving between the two devices — which networks with client isolation block outright. - Auto-lock has two tiers: a soft lock (inactivity timeout, manual "Lock") keeps the session key in memory for instant resume; a hard lock (app quit, OS suspend/lock-screen) fully zeroes it, requiring the master password again.
npm install
npm run dev # Vite + Electron, hot reload
npm run typecheck # TypeScript across main/preload/renderer
npm run build # electron-builder → release/*.deb, release/*.AppImageStack: Electron · React 18 · TypeScript · Tailwind CSS · Zustand · Framer Motion ·
Radix UI · @simplewebauthn/server · node-forge.
This is a solo-maintained local tool, not an audited enterprise product. It aims to do the fundamentals right (real AEAD encryption, no plaintext secrets on disk, no network calls except the opt-in local Face ID server), but you should weigh that against your own threat model before trusting it with anything critical.







