5.3 KiB
5.3 KiB
vault1984
Zero-knowledge password manager. Infrastructure is the moat. FIPS 140-3, BoringCrypto, built for trust.
Ground Rules
Johan is the architect. You are the collaborator. Same principles as inou:
- Discussion first. Default is conversation. No code until asked ("do it", "implement it").
- Minimal diffs. Change only what's requested. No drive-by cleanups.
- Less code, better architecture. If something needs a lot of code, the design is probably wrong.
- Ask, don't assume. Ambiguous request → ask. Don't pick an interpretation and run.
- No unsolicited files. No new docs, tests, or helpers unless explicitly asked.
- Mention concerns once, then execute. Johan has reasons. Respect them.
Repository Structure
docs/ — all design documentation (shared across OSS + commercial)
oss/ — open source, published to GitHub
app/ — vault1984 server (Go, FIPS 140-3)
cli/ — v1984 CLI client
crypto/ — crypto primitives (BoringCrypto)
Makefile — build system
commercial/ — proprietary, Zürich only, never on GitHub
account/ — account system (billing, vault credits)
mgmt/ — POP management sidecar
website/ — vault1984.com (marketing + account management)
marketing/ — marketing assets
tailscale/ — ACL config
Build: Always use GOEXPERIMENT=boringcrypto (set in Makefile). Required for FIPS 140-3.
cd oss/
make deploy # build + test + restart everything
make deploy-app # app only
make deploy-web # website only
make status # check what's running
Environments
| Environment | Host | Purpose |
|---|---|---|
| HQ / NOC | noc.vault1984.com (185.218.204.47) | Hans runs this — Hans' domain |
| Forge (local) | 192.168.1.16 | Development |
SSH: root@185.218.204.47 (HQ/Hans), ssh johan@192.168.1.16 (forge)
Security Non-Negotiables
- FIPS 140-3 via
GOEXPERIMENT=boringcrypto— never build without it - Zero-knowledge — server never sees plaintext credentials
- WebAuthn PRF — hardware key derives master secret; L2 (16 bytes) for agents, L3 (32 bytes) for humans only
- No logging of credential content, ever
- Registration = unlocked. Passkey registration MUST derive and store the master key. There is no distinction between "registered" and "logged in" — both mean the user authenticated with hardware. The vault is immediately usable after registration, no second tap.
- No "simplest fix" shortcuts. This is a world-class security product. Every flow must be correct by design, not patched after the fact.
Current Status (Mar 2026)
- Binary builds: amd64 + arm64, telemetry flag support
- POP nodes: HQ (Zürich), Virginia (us-east-1), Singapore (ap-southeast-1)
- Telemetry: binary supports
--telemetry-*flags; HQ dashboard/telemetryhandler pending - WebAuthn L2: in progress
- Permanent VAULT_KEY handling: pending
Data Access Architecture
All DB operations go through named functions in oss/app/lib/dbcore.go. No direct SQL outside dbcore.go.
Choke points:
EntryCreate/Get/Update/Delete/List/Search— all credential entry operationsSessionCreate/Get/Delete— session managementAuditLog— every security event goes here, no exceptions
FORBIDDEN outside dbcore.go:
db.QueryRow(),db.Exec(),db.Query()— direct SQL is a violation (one exception:telemetry.go— isolated, non-security code)- New wrapper functions that bypass the named choke points
- Any modification to
dbcore.gowithout Johan's explicit approval
Encryption: All credential fields are encrypted with the vault key via Pack/Unpack in dbcore.go. This is the ONLY encryption path. Never encrypt/decrypt fields outside of it.
Session & Key Architecture (DO NOT VIOLATE)
One session key, one salt, one source of truth.
- Session key:
v1984_masterinsessionStorage— 32-byte master secret, base64-encoded - HKDF salt:
vault1984-master-v2— used everywhere, no alternatives - L1 = bytes[0..8], L2 = bytes[0..16], L3 = bytes[0..32] — all derived from
v1984_master - webauthn.js is the ONLY module that derives and stores the master key
- topbar.js is the ONLY module that clears it (on lock/logout/401)
- crypto.js is the ONLY module that encrypts/decrypts fields — shared between CLI and browser
Rules:
- NEVER create a second session key (no
v1984_l2key, nov1984_foo) - NEVER derive keys with a different salt
- NEVER derive or store keys outside webauthn.js
- NEVER encrypt/decrypt outside crypto.js
- Registration = unlocked. One tap stores the master key. No second tap.
isUnlocked()checks sessionStorage — if false, user is logged out
Shared JS (crypto/ directory):
oss/crypto/crypto.jsandoss/crypto/totp.jsare the source of truth- Makefile copies them to
oss/app/cmd/vault1984/web/before building - NEVER edit the copies in
web/directly — editoss/crypto/and rebuild - CLI (QuickJS) and browser (Web Crypto) use the same code
Key Files
docs/L2_AGENT_ENCRYPTION.md— WebAuthn L2 encryption spec (SUPERSEDED by truncation model)docs/— architecture docsoss/app/cmd/vault1984— main entry pointoss/crypto/— shared JS crypto (source of truth for CLI + browser)oss/cli/— vault1984-cli (C + QuickJS + BearSSL)