The password manager for your AI coding agent sessions.
Secure, hardware-backed credential store for AI coding tool sessions — Claude Code, Cursor, Codex, Gemini CLI. Sessions are encrypted at rest using OS hardware roots (Windows DPAPI/TPM, macOS Keychain/Secure Enclave, Linux libsecret/TPM2), scoped to specific project directories, and served via a local daemon. Credentials never touch cloud storage or shell profiles.
The Bitwarden CLI was hijacked in a supply chain attack where malware specifically hunted for credentials to Claude, Cursor, and Codex CLI. Developers who store ANTHROPIC_API_KEY in .bashrc or .env files are one infostealer away from handing over access to every repository and pipeline they touch.
session.vault stores AI tool credentials the way a hardware security key stores passwords — bound to your machine, encrypted at rest, never exported to cloud storage.
- Rust toolchain (stable 1.70+): rustup.rs
- Windows: Visual Studio Build Tools (MSVC linker)
- macOS: Xcode Command Line Tools (
xcode-select --install) - Linux:
libsecret-1-devandpkg-config(sudo apt install libsecret-1-dev pkg-config)
git clone https://github.com/authnull/session-vault
cd session-vault
cargo build --releaseBinaries are written to target/release/:
session-vault(orsession-vault.exe) — the CLI you interact withsv-daemon(orsv-daemon.exe) — the background credential server
Linux / macOS:
sudo cp target/release/session-vault /usr/local/bin/
sudo cp target/release/sv-daemon /usr/local/bin/Windows (PowerShell as Administrator):
Copy-Item target\release\session-vault.exe C:\Windows\System32\
Copy-Item target\release\sv-daemon.exe C:\Windows\System32\Or add target/release/ to your PATH instead of copying.
The daemon is a background process that holds the vault encryption key in memory and serves credentials via a local IPC socket. It must be running for the CLI to work.
session-vault daemon startVerify it's running:
session-vault daemon statusVersion: 0.1.0
Uptime: 42s
Sessions stored: 0
Hardware backend: dpapi # windows
keychain # macos
libsecret # linux
Optional — run at login:
Linux (systemd user service):
systemctl --user enable session-vault
systemctl --user start session-vaultmacOS (launchd):
# Copy install/com.authnull.session-vault.plist to ~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/com.authnull.session-vault.plistWindows (Task Scheduler):
# Registers a logon-triggered task under your user account
.\install\install.ps1# Scope to a specific project directory (recommended)
session-vault add --tool claude --project /path/to/my-project
Enter ANTHROPIC_API_KEY (input hidden): sk-ant-...
Stored session 3fa85f64-5717-4562-b3fc-2c963f66afa6# Or store globally (available from any directory)
session-vault add --tool claude --global
Enter ANTHROPIC_API_KEY (input hidden): sk-ant-...
Stored session 7b2c9d1e-...Supported tools and their env vars:
| Tool | Flag | Env var stored |
|---|---|---|
| Claude Code | --tool claude |
ANTHROPIC_API_KEY |
| Cursor | --tool cursor |
CURSOR_API_KEY |
| OpenAI Codex | --tool codex |
OPENAI_API_KEY |
| Gemini CLI | --tool gemini |
GEMINI_API_KEY |
Optional flags:
# Set a human-readable label
session-vault add --tool claude --project . --label "work-laptop-main"
# Override inactivity TTL (default: 8 hours)
session-vault add --tool claude --project . --ttl 3600 # 1 hour# Load into current shell session
eval $(session-vault env --tool claude)
# Now run Claude Code normally
claude --dangerously-skip-permissions# Credentials are injected only into this subprocess
session-vault exec --tool claude -- claude --dangerously-skip-permissionsThe exec pattern is safer: credentials exist only in the subprocess environment and are never exported to your parent shell.
# Bash
session-vault install --shell bash
source ~/.bashrc
# Zsh
session-vault install --shell zsh
source ~/.zshrc
# PowerShell
session-vault install --shell powershell
. $PROFILEAfter installation, call sv_load before running AI tools:
sv_load claude # loads ANTHROPIC_API_KEY into current shell
claude ...sv_load claude
claude ...session-vault listID TOOL FINGERPRINT PROJECT EXPIRES IN
------------------------------------------------------------------------------------------------------------------------
3fa85f64-5717-4562-b3fc-2c963f66afa6 claude a1b2c3d4 /home/user/my-project 7h 58m
7b2c9d1e-4f3a-4e2b-8c1d-9e0f1a2b3c4d codex e5f6a7b8 global never
# Remove by ID
session-vault remove 3fa85f64-5717-4562-b3fc-2c963f66afa6
# Remove all Claude sessions
session-vault remove --tool claude
# Remove all sessions for a project
session-vault remove --project /path/to/projectsession-vault daemon stopsession-vault doctorThe doctor command:
- Checks the daemon is reachable
- Reports the hardware backend in use (warns if software-only)
- Scans
~/.bashrc,~/.zshrc,~/.profilefor plaintext API keys - Scans
.envfiles in the current directory for plaintext API keys
Example output:
session-vault doctor
[1] Daemon reachable ... OK
[2] Hardware backend ... OK (dpapi)
[3] Checking shell profiles for leaked API keys ...
WARN: ANTHROPIC_API_KEY found in /home/user/.bashrc
Consider removing it and using 'session-vault add' instead.
[4] Checking current directory for .env files ...
WARN: OPENAI_API_KEY found in ./.env
Consider using 'session-vault add' and removing it from the .env file.
Your terminal
│
├─ session-vault env --tool claude
│ │
│ └─ IPC socket (Unix socket / Windows named pipe)
│ │
│ └─ sv-daemon (background process)
│ │
│ ├─ Derives VEK from hardware root key
│ │ (DPAPI on Windows, Keychain on macOS, libsecret on Linux)
│ │
│ ├─ Decrypts ChaCha20-Poly1305 credential blob from vault.db
│ │
│ └─ Returns env vars over IPC (never over network)
│
└─ eval → ANTHROPIC_API_KEY is set in your shell
Key security properties:
- Credentials encrypted with ChaCha20-Poly1305 using a hardware-bound key
- Vault encryption key (VEK) derived from OS hardware root — never stored in the database
- Credentials scoped to project directories — a key for project A is never served to a process in project B
- Sessions auto-expire after inactivity (default: 8 hours) or a hard deadline
- IPC socket is owner-only (mode 0600 on Unix, restricted ACL on Windows)
- Daemon runs as your user, not root
- No network calls, no telemetry, no cloud sync
Default config locations:
| Platform | Vault DB | IPC Socket |
|---|---|---|
| Windows | %LOCALAPPDATA%\session-vault\vault.db |
\\.\pipe\session-vault-{username} |
| macOS | ~/Library/Application Support/session-vault/vault.db |
$XDG_RUNTIME_DIR/session-vault.sock |
| Linux | ~/.local/share/session-vault/vault.db |
$XDG_RUNTIME_DIR/session-vault.sock |
# Debug build (fast compile, large binary)
cargo build
# Release build (optimized, ~3-4 MB)
cargo build --release
# Run tests
cargo test --workspace
# Check for security advisories in dependencies
cargo install cargo-audit
cargo auditcrates/
├── sv-core/ # Data models, ChaCha20-Poly1305 crypto, TTL logic
├── sv-keyring/ # OS hardware key integration (DPAPI, Keychain, libsecret)
├── sv-store/ # Encrypted SQLite storage layer
├── sv-daemon/ # Background IPC server (JSON-RPC over Unix socket / named pipe)
└── sv-cli/ # User-facing CLI (session-vault binary)
session.vault is designed to defend against:
- Infostealers scanning shell profiles — keys never written to
.bashrcor.env - Supply chain attacks — minimal Rust dependency tree,
Cargo.lock-pinned, cargo-audit in CI - Disk forensics — credential blobs encrypted with hardware-bound key; raw DB file contains no usable secrets
- Cross-project credential theft — project-scope matching prevents key for project A being served to project B
- Session token persistence — inactivity TTL and hard expiry limits the window for stolen tokens
It does not defend against:
- An attacker with your OS user session (they can request credentials from the daemon just as you can)
- Physical access to an unlocked machine with the daemon running
- Malware running as your user (same threat model as any user-space credential store)