clavitor/clavis/clavis-vault
James d3e9f89bc0 Add PUT /api/agents/{id} endpoint for updating agent WL/RL
HandleUpdateAgent allows updating:
- IP whitelist (ip_whitelist array)
- Rate limit per minute (rate_limit_minute)

Does NOT allow updating (security):
- Admin status (intentionally omitted)
- All_access flag
- Scopes

Requires admin token (PRF tap) since it's a sensitive operation.
This enables the Edit Agent GUI in agents.html to save changes.
2026-04-02 02:14:00 -04:00
..
.claude chore: auto-commit uncommitted changes 2026-03-25 06:04:04 -04:00
_old feat: vault v2 rewrite — CVT tokens, scoped access, agents-as-entries, 14 importers 2026-03-31 13:36:04 -04:00
api Add PUT /api/agents/{id} endpoint for updating agent WL/RL 2026-04-02 02:14:00 -04:00
cmd/clavitor Add GUI for editing Agent WL (IP Whitelist) and RL (Rate Limit) 2026-04-02 01:22:50 -04:00
data Replication v2: Active-Passive with Async Sync (Commercial Only) 2026-04-02 00:50:20 -04:00
edition Complete replication implementation with L0/L1 auth (Commercial Only) 2026-04-02 01:21:20 -04:00
lib Complete replication implementation with L0/L1 auth (Commercial Only) 2026-04-02 01:21:20 -04:00
._.DS_Store chore: auto-commit uncommitted changes 2026-03-26 00:01:24 -04:00
._README.md chore: auto-commit uncommitted changes 2026-03-25 06:04:04 -04:00
.gitignore chore: auto-commit uncommitted changes 2026-03-25 06:04:04 -04:00
CLAUDE.md Security hardening v2: Edition system + 24 security fixes 2026-04-02 00:36:31 -04:00
GIT_WORKFLOW.md Security hardening v2: Edition system + 24 security fixes 2026-04-02 00:36:31 -04:00
LICENSE chore: auto-commit uncommitted changes 2026-03-25 06:04:04 -04:00
Makefile chore: auto-commit uncommitted changes 2026-03-29 06:01:26 -04:00
README.md seo: enhanced sitemap.xml with lastmod/priority/changefreq, added Open Graph meta tags, added JSON-LD structured data (WebSite, Organization, SoftwareApplication schemas), improved robots.txt 2026-03-29 02:24:59 -04:00
SECURITY_REVIEW_REPLICATION.md Security review: Replication functionality (Commercial Only) 2026-04-02 01:02:36 -04:00
SPEC-dual-build.md Security hardening v2: Edition system + 24 security fixes 2026-04-02 00:36:31 -04:00
SPEC-import-matrix.md feat: vault v2 rewrite — CVT tokens, scoped access, agents-as-entries, 14 importers 2026-03-31 13:36:04 -04:00
SPEC-replication-async.md Event-driven async replication (Commercial Only) 2026-04-02 00:51:51 -04:00
SPEC-replication-config.md Mandatory config file for commercial replication (no env vars) 2026-04-02 00:56:30 -04:00
SPEC-replication.md Replication v2: Active-Passive with Async Sync (Commercial Only) 2026-04-02 00:50:20 -04:00
SPEC-scopes.md feat: vault v2 rewrite — CVT tokens, scoped access, agents-as-entries, 14 importers 2026-03-31 13:36:04 -04:00
SPEC.md chore: auto-commit uncommitted changes 2026-03-25 06:04:04 -04:00
go.mod Mandatory config file for commercial replication (no env vars) 2026-04-02 00:56:30 -04:00
go.sum Mandatory config file for commercial replication (no env vars) 2026-04-02 00:56:30 -04:00

README.md

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

go build -o clavitor ./cmd/clavitor/
./clavitor
# Open http://localhost:1984/app/
# Register a passkey → vault is ready

No config files, no environment variables, no database setup.


Self-hosting and AI agents

Your vault should not run on the same machine as your AI agents.

AI agents have shell access. If the vault database is on the same filesystem, an agent can read it directly — bypassing the API, the audit log, and the encryption model.

Run the vault on a separate device. A Raspberry Pi, a NAS, a VM, or a VPS — anything the agent can reach over HTTPS but cannot SSH into. Even a $5/month VPS works, or look for a hosted Clavitor solution.

If you must run on the same machine: create a dedicated system user for the vault, restrict the database file to that user (chmod 600), and run the vault as a systemd service under that account. This is not equivalent to network isolation, but it raises the bar.


Create a token in the web UI (Tokens page), then add to your MCP client config:

{
  "mcpServers": {
    "clavitor": {
      "url": "http://localhost:1984/mcp",
      "headers": {
        "Authorization": "Bearer clavitor_..."
      }
    }
  }
}

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.

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:

  • Chromechrome://settings/passwords → export CSV
  • Firefoxabout: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.

./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

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


License

Elastic License 2.0 — free to use, modify, and self-host. Cannot be offered as a managed service to third parties.