Skip to content
JorikSchellekensPublic

About

Matrix Based Password Manager

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Vaultrix

An end-to-end encrypted password manager that syncs over Matrix.
Your vault is a private encrypted room. Your server is any Matrix homeserver.

License: MIT Built on Matrix Status: alpha TypeScript


Vaultrix stores your passwords as an append-only, end-to-end encrypted event log in a private Matrix room. There is no Vaultrix server and no account to create with us: any Matrix homeserver, including one you run yourself, is the sync backend, and it only ever sees ciphertext.

Why Matrix?

Matrix already solved the hard problems of a password manager backend, so Vaultrix leans on the real thing instead of reinventing it:

  • Item history and undelete. The room timeline is an append-only version log. Every change to every entry is recoverable by design, a feature other managers paywall.
  • Multi-device sync. Devices converge through ordinary Matrix sync; a live timeline watcher applies changes from your other devices as they arrive.
  • Recovery. The standard Matrix recovery key (SSSS) is the vault's "secret key". One key, printable on an emergency kit, unlocks everything on a fresh device.
  • Shared vaults. Rooms, invites, and power levels are exactly the substrate a shared family or team vault needs (on the roadmap).
  • Self-hosting. Run Synapse or any other homeserver and you own the whole stack.

Features

  • One vault per private Megolm-encrypted room, with all vault semantics client-side
  • Double encryption: entries are AES-256-GCM encrypted under a vault master key before Megolm ever sees them
  • Fresh-device unlock with a standard Matrix recovery key, restoring from mandatory server-side key backup
  • TOTP and HOTP code generation, tested against the RFC vectors
  • Conflict resolution that can never resurrect a deleted entry (per-entry last-write-wins with tombstones)
  • Key rotation with vault epochs, snapshot compaction for fast cold starts
  • Vault export and recovery-key QR codes
  • One core, three frontends: MV3 browser extension, web UI, and Tauri desktop app

Status

Alpha, under active development. The Matrix E2EE layer is the standard audited stack (matrix-js-sdk with vodozemac), but Vaultrix itself has not had an independent security review. Do not make it the only copy of credentials you care about yet.

How it works

flowchart LR
    subgraph device["Your device"]
        OP["Vault op<br/>(create / update / delete)"] -->|"AES-256-GCM under K_vault"| APP["App-layer ciphertext"]
        APP -->|"Megolm room encryption"| EV["Matrix event"]
    end
    EV --> HS[("Homeserver<br/>ciphertext only")]
    SSSS["Secret storage (SSSS)<br/>holds K_vault + backup key"] -.->|"recovery key"| OP
Loading
  • One vault = one private Megolm-encrypted Matrix room. Entries live as an append-only log of custom com.vaultrix.vault.v1.op events, with periodic ...snapshot events for compaction.
  • Double encryption. Each op/snapshot payload is encrypted app-side with a 32-byte vault master key K_vault (AES-256-GCM), then the event itself is Megolm-encrypted by the room like any Matrix message.
  • K_vault lives in Matrix secret storage (SSSS), protected by the standard Matrix recovery key created when the vault is provisioned.
  • Key backup is mandatory for vaults. Provisioning enables server-side key backup; a fresh device unlocks by loading the backup key from SSSS and restoring Megolm keys, then back-paginating the room to the start and replaying snapshot + ops. This is the canonical matrix-js-sdk flow (E2EE docs, vodozemac via initRustCrypto()).
  • Conflict resolution is last-write-wins per entry with tombstones: the (ts, op_id) of the last applied op is tracked per entry id, so a stale update can never resurrect a deleted entry.
  • Key rotation bumps the vault epoch: new K_vault in SSSS, fresh snapshot encrypted with the new key; ops from older epochs are ignored.

Unlock flow on a fresh device:

  1. Password login, then initRustCrypto() and an initial sync
  2. Recovery key opens SSSS, yielding K_vault
  3. Megolm keys restore from server-side key backup
  4. The vault room is back-paginated fully, decrypted, latest snapshot applied, later ops replayed
  5. A live timeline watcher applies ops from other devices as they arrive

What the homeserver can see

The homeserver stores only doubly-encrypted payloads. It does see metadata: which user talks to which rooms, event timestamps and sizes, and your device list. It never sees entry contents, titles, URLs, or K_vault. Even a future Megolm key compromise alone is not enough to read entries, since payloads are still AES-GCM encrypted under K_vault.

Getting started

Prerequisites: Node >= 18, pnpm 9, and Docker if you want to run the integration or e2e suites.

pnpm install
pnpm run build            # all packages
pnpm run build:extension  # core + ui + extension bundle

Browser extension

Build, then open chrome://extensions, enable "Developer mode", choose "Load unpacked", and select extension/dist. In the popup, "Open vault" opens the options page with the full unlock and vault UI.

Web UI

pnpm run dev:ui

Desktop app (Tauri 2)

pnpm run dev:tauri     # development
pnpm run build:tauri   # release build

Both scripts regenerate tauri/icons/icon.png from assets/ via pnpm run ensure-tauri-icon (the file is required by Tauri's generate_context!() and is not checked in).

Testing

pnpm run test              # core unit tests (crypto, LWW model, TOTP RFC vectors, ...)
pnpm run test:integration  # full vault lifecycle against a throwaway Synapse (needs Docker)
pnpm run test:e2e          # Playwright browser e2e of the web UI (needs Docker)
pnpm run test:all

The integration suite spins up a disposable Synapse container and exercises the real thing end to end: provisioning (SSSS + key backup + room + K_vault), writing entries past the sync-window size, fresh-device unlock via recovery key, live multi-device sync, delete/LWW semantics, snapshot compaction, and key rotation.

Project layout

Path What lives there
packages/core Matrix client wrapper, vault room, SSSS + key backup, vault model (LWW + tombstones), op log, snapshots, session (unlock + watch), provisioning, rotation, export, recovery QR, TOTP/HOTP
packages/ui React app: unlock screen, vault list. The same bundle serves the extension options page and the Tauri app
extension MV3 browser extension: background service worker (Matrix + vault), popup, content script (autofill), options page
tauri Tauri 2 desktop shell around the UI bundle, with Rust capabilities (clipboard, shell-open)
assets Logo and icon sources (SVG masters plus rendered PNGs)

Roadmap

The durable spec and phased roadmap live in SPEC.md. The current focus is the browser extension: inline autofill, save/update prompts, a password generator, and TOTP fill.

Contributing

Issues and pull requests are welcome. Before submitting, please run pnpm run test; run the integration suite too if you touched anything in packages/core. Keep changes scoped and include tests for new vault semantics.

License

MIT

About

Matrix Based Password Manager

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages