117 lines
5.3 KiB
Markdown
117 lines
5.3 KiB
Markdown
# 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:
|
|
|
|
1. **Discussion first.** Default is conversation. No code until asked ("do it", "implement it").
|
|
2. **Minimal diffs.** Change only what's requested. No drive-by cleanups.
|
|
3. **Less code, better architecture.** If something needs a lot of code, the design is probably wrong.
|
|
4. **Ask, don't assume.** Ambiguous request → ask. Don't pick an interpretation and run.
|
|
5. **No unsolicited files.** No new docs, tests, or helpers unless explicitly asked.
|
|
6. **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.
|
|
|
|
```bash
|
|
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 `/telemetry` handler 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 operations
|
|
- `SessionCreate/Get/Delete` — session management
|
|
- `AuditLog` — 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.go` without 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_master` in `sessionStorage` — 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`, no `v1984_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.js` and `oss/crypto/totp.js` are the source of truth
|
|
- Makefile copies them to `oss/app/cmd/vault1984/web/` before building
|
|
- NEVER edit the copies in `web/` directly — edit `oss/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 docs
|
|
- `oss/app/cmd/vault1984` — main entry point
|
|
- `oss/crypto/` — shared JS crypto (source of truth for CLI + browser)
|
|
- `oss/cli/` — vault1984-cli (C + QuickJS + BearSSL)
|