06PERSONALIN PROGRESS2025

Local Password Manager

Product lab · Security engineering

A personal security-engineering project exploring a product that keeps vault operations on the user's device.

The problem

A password manager’s browser extension needs convenient access to secrets that live in a desktop vault — and the moment the two talk over localhost, the vault has effectively opened a network service on the machine. Anything local can knock.

Local-first doesn’t remove the trust boundary; it moves it. The question becomes: how does the desktop app know a request really came from the paired extension, is fresh, isn’t a replay, and is for a site the credential actually belongs to?

The approach

CipherBox keeps the vault in a Tauri v2 + Rust desktop app: secrets encrypted with XChaCha20-Poly1305 under an Argon2id-derived key, in a locked-down SQLite file. The Chrome extension never stores or derives keys — it talks to the desktop over a loopback HTTP bridge where every request is HMAC-signed, timestamped and nonce-protected.

Autofill is two-phase by design: the extension may ask for matching item metadata, but an actual secret is released only after a real user click, and the desktop independently re-validates the requesting site before answering.

My role — Security architecture and product exploration; not represented as production-ready software.

TauriRustChrome extensionHMAC-SHA256OS keychainArgon2idXChaCha20-Poly1305

How it works, step by step

Credential fill — the implemented flow

Every value shown is masked dummy data. No passwords appear anywhere on this page.

UserChrome extensionMV3 · content scriptLoopback bridge127.0.0.1 · signedrequestsCipherBox desktopTauri v2 · RustEncrypted vaultXChaCha20-Poly1305 ·SQLitemacOS Keychainpairing key · Touch IDclick

01Pair once

Pairing starts on the desktop, not in the browser: the user asks the unlocked app for a code, enters it in the extension, and the two are bound.

Select any node in the diagram to inspect it.

Person
Connected system
Internal layer
This project
Data at rest
Info
Success

Architecture

Architecture

Local-first: the only implemented transport for secrets is a signed loopback hop on one machine.

Chrome extensionMV3Signed loopback bridgeHMAC · nonce · originTauri / Rust appvault logic · passkeysEncrypted vaultArgon2id · XChaCha20macOS Keychainsecure-enclave backed.pvault local backupsencrypted before writeBackup Worker + R2written & testedPARTIAL
Connected system
Internal layer
This project
Data at rest
Partial (not built yet)
Connected system
Internal layer
This project
Data at rest
Partial (not built yet)

Passkeys follow an even stricter path than passwords: P-256 private keys never leave Rust, and each WebAuthn request waits (max 60 seconds, in memory only) for explicit approval in the desktop UI, with the relying-party ID validated in Rust and again in the extension.

Key engineering decisions

  • Local encrypted vault
  • Loopback bridge
  • Signed requests
  • Replay protection
  • Optional encrypted backup

Switch to the technical view for the engineering trade-offs behind these.

Challenges & limitations

  • macOS only for now: OS secure storage and Touch ID are implemented against the macOS Keychain; other platforms return an explicit error rather than a weaker fallback.
  • v1.0.0-rc.1 is a release candidate: the app and DMG build and run, but are ad-hoc signed — no Developer ID, no notarization, and the auto-updater is intentionally inert.
  • Cloud backup is written and tested but deliberately not enabled (see architecture). Local encrypted .pvault files are the only shipping backup path.
  • The security review is an internal, AI-assisted one — valuable, verified, and not a substitute for an independent external audit. This is a security-engineering lab project, not a product claiming production certification.

What I learned

Local-first doesn’t delete the trust boundary — it relocates it to process identity, IPC design and key lifecycle. The most instructive bugs were never in the cipher; they were in how a pairing code was issued, where a secret passed through argv, and which layer got to decide a domain matched.

Project status

v1.0.0-rc.1 — personal security lab

Working vault, extension, TOTP, passkeys, Touch ID and encrypted local backup, with a built macOS app and DMG on disk. Held at release-candidate pending signing, notarization and real-device acceptance — and explicitly not marketed as audited or production-certified.