Svault
The secret manager that knows an AI is asking.
Svault is an AI-aware secret access layer written in Rust. It sits between AI agents and your credentials — enforcing structured requests, detecting suspicious patterns, and making sure an agent has a real reason before it touches anything sensitive.
Why Svault? Every existing secret manager (1Password, Infisical, HashiCorp Vault) treats an AI agent the same as a human or a script. Svault doesn't. It knows the difference.

Install
From crates.io (recommended)
From source
Binary install (coming soon)
|
Interactive mode (TUI)
Run svault with no subcommand to open the full-screen terminal UI:
From the keyboard you can browse all vaults (with live lock state), c create,
u unlock / l lock, s edit settings, and — once a vault is unlocked —
a add, view, and d delete secrets. The TUI reuses the cached session
passphrase, so an unlocked vault is never re-prompted. Every subcommand below
still works for scripting and automation.
Quick Start
# 1. Create an encrypted vault (prompts for name, description, agents,
# rate limit, auto-lock, auto-lock timer, login method, passphrase)
# 2. Add secrets (use --vault NAME when you have more than one vault)
# 3. Unlock for your session (passphrase cached, not prompted again)
# 4. Use secrets without re-entering passphrase
# 5. View or change a vault's settings
# 6. Check lock status
# 7. Lock when done
How it works
AI Agent / User
│
│ svault_get_secret(name, scope, reason) ← reason required (Step 2+)
▼
┌──────────────────────────────────┐
│ Svault daemon │
│ │
│ Multi-factor auth │
│ (Passphrase, YubiKey, │
│ TOTP, Touch ID/Face ID) │
│ │
│ Policy checks: │
│ reason → capability → rate limit│
│ burst detection, audit log │
│ Claude anomaly score (cloud) │ ← optional
│ sensitivity tier enforcement │
└──────────────┬───────────────────┘
│
▼
.svault/<vault>/vault.enc ← AES-256-GCM encrypted, safe to commit
Authentication options (Step 3+, choose any combination):
- Passphrase — Always available, works everywhere
- YubiKey — Hardware HMAC-SHA1 challenge-response
- Google Authenticator — Time-based OTP (TOTP)
- Touch ID / Face ID — macOS biometric unlock
The reason field is required by the policy engine (below). An AI that cannot explain why it needs a secret is refused immediately.
Policy engine (Step 2)
svault secret get is the human path — passphrase, no questions asked. svault get is the agent path: a structured request that an AI must justify, run through a pipeline before any secret is handed over.
svault get DB_URL --scope database --reason "run nightly migration" --caller claude-code
│
├─ identify caller (--caller, else $SVAULT_CALLER, else "default")
├─ reason required (rejects empty / too-short / placeholder reasons)
├─ capability check (caller holds the scope AND it matches the secret)
├─ sensitivity tier (low=allow, medium=allow+log, high=deny)
├─ rate limit + burst (per-caller, from the audit log)
└─ audit log (every allow/deny appended, never the value)
On allow, the secret value is printed to stdout (status goes to stderr, so agents capture only the value). On deny, it exits non-zero and logs why. high-tier secrets are never handed to an agent — a human retrieves those with secret get.
Policy lives in a committable svault.policy.yaml at the project root (it holds no secrets):
version: 1
callers:
claude-code:
scopes:
rate_limit: 20/hour
default: # applies to any unlisted caller
scopes:
rate_limit: 5/hour
vaults:
my-project:
secrets:
DB_URL:
DB_PASSWORD:
API_KEY:
"*": # default for unlisted secrets
Run svault policy init to scaffold one, and svault policy check <caller> to see what a caller can access plus its recent activity. Each request is recorded to .svault/<vault>/audit.log (gitignored).
No policy file? svault get falls back to the vault's meta.yaml allow_agent / rate_limit settings (a reason is still required), so the policy file is optional but recommended.
Vault structure
.svault/
my-project/
vault.enc ← AES-256-GCM encrypted secrets (safe to commit)
meta.yaml ← name, description, access rules (safe to commit, HMAC-signed)
.gitignore ← auto-written at create, blocks .session + audit.log from being committed
.session ← passphrase cache while unlocked (gitignored, mode 0600)
audit.log ← policy decisions for 'svault get' (gitignored, mode 0600)
vault.enc and meta.yaml are safe to commit. They are useless without the passphrase.
.session is always gitignored and created with mode 0600 (owner read/write only).
Commands
# Policy engine — the agent path (Step 2)
# VAULT is positional for create/settings/unlock/lock; secret & get use -v/--vault.
# Omit it to use the only vault, or get prompted to pick when several exist.
Security
| Property | Implementation |
|---|---|
| Encryption | AES-256-GCM |
| Key derivation | Argon2id (64MB memory, 3 iterations) — GPU-resistant |
| Metadata integrity | HMAC-SHA256 — tampering with meta.yaml is detected |
| Memory safety | VaultKey and secrets derive ZeroizeOnDrop — wiped on drop |
| Session file | Created atomically with mode 0600, never at permissive permissions |
| Vault file | Safe to commit to git — encrypted at rest |
The passphrase is the only key. Strong passphrase + Argon2id = brute force is not practical with current hardware.
Roadmap
| Phase | Status | What |
|---|---|---|
| Step 1 | DONE | Local encrypted vault with AES-256-GCM + Argon2id |
| Step 1+ | DONE | Interactive Ratatui TUI (run svault with no args) — forms, browsers, lock-aware secret management |
| Step 2 | DONE | Policy engine — svault get with caller identity, reason, scope capability checks, sensitivity tiers, rate limiting + burst detection, audit log |
| Step 3 | TODO | Daemon + multi-select auth (Passphrase, YubiKey, TOTP, Touch ID/Face ID) |
| Step 4 | TODO | Desktop GUI (Tauri) for vault management + system tray |
| Step 5 | TODO | MCP integration — Claude Code, Cursor, Copilot, VS Code, Aider |
| Cloud | TODO | Anomaly scoring via Claude Haiku — free tier + premium plans |
Tests
33 tests covering: roundtrip encryption, wrong key rejection, bit-flip authentication failure, different salts produce different keys, vault create/open, wrong passphrase, add/get/list/remove, persistence across reopen, tampered vault.enc rejected, tampered meta.yaml rejected, session unlock/lock/lock-all, passphrase strength checks, audit log record/read, rate-limit parsing, and the policy engine (capability, tiers, rate limit, burst, unknown caller, fallback mode).
CI runs the suite on Ubuntu, Fedora, macOS, and Windows on every push and pull request.
License
Apache 2.0 — see LICENSE
Built by Soluzy