214 lines
9.4 KiB
Markdown
214 lines
9.4 KiB
Markdown
# clavitor
|
|
|
|
> *"If you want to keep a secret, you must also hide it from yourself."*
|
|
> — George Orwell, 1984
|
|
|
|
**A password manager where a breached server gives attackers nothing.**
|
|
|
|
Not because we delete the data. Not because we encrypt it harder.
|
|
Because the decryption key was never there to begin with.
|
|
|
|
Managed hosting or self-hosted. Open source. Three encryption layers.
|
|
One binary. One SQLite file.
|
|
|
|
---
|
|
|
|
## Why the architecture matters
|
|
|
|
In 2022, attackers stole the entire vault database of a leading password manager. The encryption worked exactly as designed. The problem was structural: when you store encrypted data on a server that also holds the decryption capability, a breach gives attackers unlimited offline time to crack. Four years later, accounts are still being drained from that breach. The industry's response has been higher iteration counts — making the vault harder to crack. clavitor's response was to make it worthless to steal.
|
|
|
|
Everything in your vault is encrypted. What differs is who holds the key.
|
|
|
|
| Layer | Contains | Key held by |
|
|
|-------|----------|-------------|
|
|
| **Vault** | Titles, URLs, usernames | Server — by design. Knowing you have a Coinbase account isn't an attack. |
|
|
| **Credential** | Passwords, API keys, TOTP seeds, SSH keys | Your agents — delegated by you. The server never had it. |
|
|
| **Identity** | Card numbers, CVV, government IDs, seed phrases | You only — hardware authenticator required. Agents cannot reach it. |
|
|
|
|
**Threat model:**
|
|
|
|
| Scenario | Vault | Credential | Identity |
|
|
|----------|-------|------------|----------|
|
|
| Database stolen | Readable (with vault key) | Worthless ciphertext | Worthless ciphertext |
|
|
| Server compromised | Visible during request | Ciphertext — server cannot decrypt | Not present |
|
|
| Agent token compromised | Via MCP | Decryptable by that agent | Not present |
|
|
| Hardware key + PIN stolen | Everything | Everything | Everything |
|
|
|
|
### How storage works
|
|
|
|
The vault does not encrypt your credentials. You do.
|
|
|
|
Credential and Identity fields are encrypted by the browser or agent before they leave the client. The vault receives the encrypted blobs, wraps everything with Vault Encryption (VAULT_KEY) for storage, and returns it on read. The server handles pack/unpack — it never inspects what's inside Credential or Identity fields.
|
|
|
|
Each field carries a `layer` tag (`vault` / `credential` / `identity`) so the client knows what it can decrypt after unpack.
|
|
|
|
**Credential key derivation:** X25519 keypair derived via HKDF-SHA256 from your WebAuthn authenticator's PRF output. Public key stored on server. Private key derived client-side during browser session and baked into agent tokens at creation time — never stored on server. Agents unwrap it locally.
|
|
|
|
**Identity key derivation:** AES-256 symmetric key derived via HKDF-SHA256 from the same PRF output (independent branch). Browser-only. Never leaves the client. Not in tokens. Not in the database.
|
|
|
|
One root of trust: your hardware authenticator. One tap unlocks both Credential and Identity layers in the browser.
|
|
|
|
---
|
|
|
|
## Quick start
|
|
|
|
```bash
|
|
go build -o clavitor ./cmd/vault1984/
|
|
./clavitor
|
|
# Open http://localhost:1984/app/
|
|
# Register a passkey → vault is ready
|
|
```
|
|
|
|
No config files, no environment variables, no database setup.
|
|
|
|
---
|
|
|
|
## MCP setup
|
|
|
|
Create a token in the web UI (Tokens page), then add to your MCP client config:
|
|
|
|
```json
|
|
{
|
|
"mcpServers": {
|
|
"clavitor": {
|
|
"url": "http://localhost:1984/mcp",
|
|
"headers": {
|
|
"Authorization": "Bearer v1984_..."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
The token is a combined credential: MCP auth + the Credential private key (wrapped). The agent decrypts Credential-layer fields locally. The server never sees the key.
|
|
|
|
### Available tools
|
|
|
|
| Tool | Description |
|
|
|------|-------------|
|
|
| `get_credential` | Find and return a credential by query |
|
|
| `list_credentials` | List all accessible entries |
|
|
| `get_totp` | Get live TOTP code for 2FA |
|
|
| `search_vault` | Full-text search across entries |
|
|
| `check_expiring` | Find expiring credentials, cards, documents |
|
|
| `save_credential` | Write a new or updated credential (write-enabled tokens only) |
|
|
|
|
Identity-layer fields return `[Identity Encryption — hardware key required]` to agents. They are not accessible without a browser session and physical authenticator tap.
|
|
|
|
Tokens are read-only by default. Write access is granted explicitly when creating the token.
|
|
|
|
---
|
|
|
|
## Features
|
|
|
|
- **One binary** — Go, compiles to linux/mac/windows. FIPS mode available (`GOEXPERIMENT=boringcrypto`)
|
|
- **One file** — SQLite per vault. Portable, copy it anywhere
|
|
- **No master password** — WebAuthn only. Touch ID, Face ID, YubiKey, Titan Key, Windows Hello
|
|
- **Three-layer field encryption** — Vault / Credential / Identity, per-field, auto-detected on import
|
|
- **Client-side encryption** — browser and agents encrypt before sending. The vault stores what it receives.
|
|
- **AI agent integration** — MCP tools for reading and writing credentials, completing 2FA flows autonomously
|
|
- **Auto-detection** — imports auto-flag card numbers, CVV, government IDs, recovery codes as Identity layer across 15+ languages
|
|
- **Auto-lock** — 60s idle + 15s countdown. Session and key cleared on lock
|
|
- **TOTP generation** — agents can complete 2FA flows without user intervention
|
|
- **Browser extension** — Manifest V3, LLM field mapping, autofill on any site
|
|
- **No content scripts** — the extension injects nothing into pages
|
|
- **Native import** — Chrome, Firefox, Bitwarden, Proton Pass without LLM. Any format via LLM fallback
|
|
- **Smart dedup** — collision resolution by source modification date
|
|
- **Automatic backups** — weekly, 3-month retention, deterministic slot per vault ID
|
|
- **Audit log** — every access logged with actor (web / extension / MCP / agent name)
|
|
- **Multi-tenant** — hosted mode, token identifies the vault. The Elastic License 2.0 prohibits offering this as a managed service to third parties — clavitor.com is the only authorized hosted service.
|
|
|
|
---
|
|
|
|
## Config
|
|
|
|
All optional. Set via environment or `.env` file in the working directory.
|
|
|
|
```bash
|
|
PORT=1984 # default
|
|
DATA_DIR=. # directory for vault DB files
|
|
MODE=self-hosted # or "hosted" for multi-tenant
|
|
VAULT_KEY=... # server-side encryption key for storage
|
|
FIREWORKS_API_KEY=... # for LLM import of unknown formats
|
|
```
|
|
|
|
`VAULT_KEY` is the server's storage key — it wraps all data at rest, including Credential and Identity blobs. Losing it makes the database unreadable. It does not give access to Credential or Identity plaintext — those require the client-side keys derived from your hardware authenticator.
|
|
|
|
---
|
|
|
|
## Import
|
|
|
|
Encryption happens in the browser. The vault never sees plaintext Credential or Identity fields during import.
|
|
|
|
**Import flow:**
|
|
1. Browser downloads existing encrypted entries from the vault and decrypts them locally
|
|
2. Browser parses the import file — natively for known formats, or sends the file to the server for LLM parsing; server returns parsed plaintext to the browser without storing it
|
|
3. Browser matches against existing entries — URL, username, and decrypted values
|
|
4. Browser shows preview: new / update / skip
|
|
5. User confirms — browser encrypts all changes and sends a single batch to the vault
|
|
|
|
Native parsing (no LLM, no server) for:
|
|
- **Chrome** — `chrome://settings/passwords` → export CSV
|
|
- **Firefox** — `about:logins` → export CSV
|
|
- **Bitwarden** — Settings → Export → JSON
|
|
- **Proton Pass** — Settings → Export → JSON (zip or plain)
|
|
|
|
Any other format: drag and drop, LLM parses it server-side and returns structure to the browser.
|
|
|
|
Collision rule: newest modification date wins. Per entry, where timestamps are available.
|
|
|
|
Identity-layer auto-detection on import covers card numbers, CVV, government IDs (SSN, passport, driver's license, BSN, PESEL, etc.), recovery codes, and crypto wallets — in English, Dutch, German, French, Spanish, Portuguese, Italian, Chinese, Japanese, Korean, Russian, Arabic, Hindi, Turkish, Polish, Swedish, Thai, and Vietnamese.
|
|
|
|
---
|
|
|
|
## Backups
|
|
|
|
Automatic weekly backups with 3-month retention. Each vault's backup slot is deterministic — the first byte of the vault ID maps to an hour of the week, spreading backup load evenly across nodes.
|
|
|
|
Backups use SQLite `VACUUM INTO` for consistent, compacted snapshots stored in `{DATA_DIR}/backups/`.
|
|
|
|
From the web UI: view all backups, trigger immediate backup, restore (current DB saved as pre-restore backup first).
|
|
|
|
---
|
|
|
|
## Telemetry
|
|
|
|
Optional push telemetry for monitoring hosted nodes. Disabled by default.
|
|
|
|
```bash
|
|
./clavitor \
|
|
--telemetry-freq 60 \
|
|
--telemetry-host https://your-monitoring-endpoint/telemetry \
|
|
--telemetry-token <bearer-token>
|
|
```
|
|
|
|
Or via environment: `TELEMETRY_FREQ`, `TELEMETRY_HOST`, `TELEMETRY_TOKEN`.
|
|
|
|
Reports: hostname, uptime, OS/arch, CPU/memory/disk usage, vault count, total entries. No vault contents, no credentials, no user data.
|
|
|
|
---
|
|
|
|
## Testing
|
|
|
|
```bash
|
|
go test ./api/... -v
|
|
```
|
|
|
|
No setup required. Each test spins up an in-process server with a temp SQLite database.
|
|
|
|
---
|
|
|
|
## Managed hosting
|
|
|
|
Don't want to run the server? We host it.
|
|
|
|
Same cryptographic guarantees. We run the infrastructure. We cannot read your Credential or Identity fields — not policy, math. The plaintext was never sent to us.
|
|
|
|
→ [clavitor.com](https://clavitor.com)
|
|
|
|
---
|
|
|
|
## License
|
|
|
|
[Elastic License 2.0](LICENSE) — free to use, modify, and self-host. Cannot be offered as a managed service to third parties.
|