Unseenkey keeps your API keys in an encrypted vault on your machine and hands out handles instead.
A handle looks like a key to the SDK that receives it, but it only works through the local broker,
which swaps it for the real key at the last moment, checks a policy (host, endpoints, rate, expiry,
approval), scrubs the key out of responses and writes every call to a tamper-evident audit log.
Includes an MCP server for Claude Code, Claude Desktop, Cursor and Windsurf, Windows Hello unlock,
and signed auto-updates.
README
Unseenkey
Let AI agents, scripts and the people you hire use your API keys — without ever seeing them.
Every SDK, .env file and AI agent asks for the raw key, and once it exists in plaintext it gets pasted into a chat, committed to git, printed in a log, or handed to a contractor you'll never see again. Unseenkey keeps the key in an encrypted vault on your machine and hands out a handle instead. The handle looks like a key to whatever receives it, but it only works through the local broker, which swaps it for the real key at the last moment, checks a policy, scrubs the key out of the response, and writes every call to a tamper-evident log.
A leaked handle costs you nothing. A leaked key costs you until you notice.
> Status: v0.1, alpha. Works and is tested on Windows, macOS and Linux. Not yet externally audited: use it with keys you can rotate. Delegating keys to other people through a hosted broker is designed, not built.
How it works
Two minutes with Claude Code
usk init # pick a password; write down the 24 recovery words
usk add anthropic # paste the key at a hidden prompt; provider detected, host-locked
usk env anthropic --policy chat # prints ANTHROPIC_BASE_URL + ANTHROPIC_API_KEY=usk_h_…
claude -p "hello" # Claude Code now calls Anthropic through the broker
usk log # every call, hash-chained
--shell powershell|cmd|dotenv prints the variables for your shell or .env. The daemon starts itself on first use, listens on loopback only, and locks after 15 minutes without a request or when the screen locks or the machine sleeps.
Or give your AI tools the tools, in one command:
usk mcp install
It finds Claude Code, Claude Desktop, Cursor and Windsurf on your computer and connects them, makes the vault first if you don't have one, offers to add your first key, and checks that the connection answers. Run it again whenever you like; it changes nothing that already works. Then restart the tool and ask it what API keys it can use. It calls APIs through Unseenkey and never sees a key.
Claude Code also has a plugin, if you'd rather install it that way. Use the plugin or usk mcp install, not both, or Claude Code gets the tools twice. The plugin needs Unseenkey 0.1.7 or later.
claude plugin marketplace add Bhagyesh97/unseenkey
claude plugin install unseenkey@unseenkey
What a handle can do
Policy per handle
Presets for each provider (stripe:payments = take payments, no refunds or payouts), explained in plain English. Expiry, request caps, time windows, approvals.
Hard caps
--cap 500/day: the 501st request is refused before it leaves the machine. Caps count requests, not money.
Canaries
--canary: a handle that never works. Plant it in .env.example; any use means someone has your files, and the vault locks.
Incident responses
A burst of refused requests throttles, pauses, asks you, or locks the vault — your choice per handle.
Approvals
Live prompts in the desktop app or usk approve: allow once, allow always, deny.
Camouflage
Handles shaped like the provider's own keys (sk-proj-usk-…) for SDKs that validate formats. Every format carries the usk marker.
AWS and OAuth2
boto3, the AWS CLI and the JS SDK sign with a placeholder; the broker re-signs with the real key. OAuth2 refresh tokens stay in the vault; the broker keeps the access token fresh.
MCP server
usk mcp install, or the Claude Code plugin: the agent gets tools, never values. A tool connects itself on first use; taking over or reconnecting an existing one needs your password.
Projects
Group keys by the app that uses them. usk project protect (or "Protect a project" in the app) moves a folder's .env keys into the vault in one step; AI tools working in that folder see only its keys, and a daily request limit per project stops a runaway bill.
.env guard
usk guard fix .env moves real keys into the vault and rewrites the file with handles.
Desktop app
Projects with a status panel, keys, agent access, approvals, activity with chain verification, one-click MCP setup, Windows Hello, signed auto-updates.
More of the same:
usk handle create stripe --policy payments --expires-days 7 --cap 500/day # for a contractor: gone next week
usk handle create stripe --canary # a tripwire for .env.example
usk add aws-dev && usk env aws-dev # boto3 and the AWS CLI through the broker
usk add google-oauth # paste a refresh token or gcloud's ADC file
usk add gsc --file key.json --scope webmasters.readonly # a Google service account; the file stays in the vault
usk add twilio # keys in two parts: asks for each, or paste first:second
usk run --with DATABASE_URL=prod-db -- ./app # for what cannot be proxied (audited, scrubbed)
Why not just…
A .env file
A secrets manager (Doppler, Infisical, 1Password CLI, Vault)
Your own proxy
Unseenkey
Your AI tool never sees the real key
No
No, it is injected into the process
Yes
Yes
Works offline, no account
Yes
Usually needs an account or a server
Yes
Yes
Rules per call: host, path, method
No
No
If you build them
Presets for 73 providers
Asks you before risky calls
No
At most for reading a secret, not per call
If you build it
Yes, confirmed with Windows Hello or your password
Removes the key from responses
No
No
If you build it
Yes, streamed and compressed too
Request limits, to stop a runaway bill
No
No
If you build them
Per handle and per project
Tamper-evident log of every call
No
Logs secret reads, not API calls
If you build it
Yes
AWS signing and OAuth refresh
The key sits in the file
The key reaches the SDK
If you build them
Done inside the broker
Already use a vault? Keep it. A vault stores keys; Unseenkey stops them reaching the agent. Importers for 1Password, Bitwarden and the OS keychain are on the roadmap (#4).
Built your own proxy? So have others: Infisical Agent Vault, fnox and OneCLI share the core idea. Unseenkey focuses on the person who owns the key: a desktop app with approvals, AWS re-signing, OAuth refresh, canary keys, a log that catches deleted entries, and next, lending a key to someone you hire.
Install
scoop bucket add unseenkey https://github.com/Bhagyesh97/scoop-unseenkey && scoop install usk # Windows
brew install Bhagyesh97/unseenkey/usk # macOS, Linux
winget install Unseenkey.Unseenkey # desktop app, Windows (listing under review)
cargo install --locked --git https://github.com/Bhagyesh97/unseenkey usk # from source, Rust 1.85+
Archives and installers for every platform are on the Releases page: CLI for Windows x64, macOS arm64/x64 and Linux x64/arm64; NSIS/MSI, DMG, deb/rpm/AppImage for the desktop app. Every archive has a Sigstore signature, every installer a minisign signature, and each release ships an SBOM. The installers are not yet code-signed, so Windows SmartScreen and macOS Gatekeeper warn on first launch.
Providers
Provider
Presets
Provider
Presets
Anthropic, OpenAI
chat, no-admin, full
GitHub
read-only, contribute, full
Groq, Mistral, OpenRouter
chat, no-admin, full
Stripe
read-only, payments, full
Google AI
generate, full
Slack, Notion, Cloudflare, Vercel
read-only, write, full
AWS
s3-read-only, s3, full
SendGrid, Resend
read-only, write, full
Supabase
read-only, data, full
Twilio
read-only, messaging, full
Plus 55 more with a safe default or read-only, and full: xAI, Together, Fireworks, Deepgram, ElevenLabs, AssemblyAI, Cohere, DeepSeek, Replicate, Perplexity, Cerebras; Paddle, Polar, Paystack, Mollie, Mercado Pago, Lemon Squeezy, Square; DigitalOcean, Linode, Vultr, Hetzner, Netlify, Render, Heroku, Neon, Supabase management, Hostinger; Postmark, Brevo, Mailgun, Loops, beehiiv, Vapi, Telnyx, Plivo, Vonage, Discord bots; Razorpay, Google service accounts, Cloudinary, Jira and Confluence, DataForSEO; Figma, Airtable, ClickUp, Coda, Calendly, Tally, HubSpot, Clerk, CircleCI, Mapbox, YouTube, OpenWeatherMap and Alpha Vantage.
Paste a key and the provider, its allowed websites and a safe default fill in, from the key's shape or, failing that, its name; then one read-only request checks the key works. generic covers any other host, Google service account key files sign in by themselves, OAuth2 refresh-token clients cover Google and anything RFC 6749, and usk presets lists everything with plain-English explanations. The provider research covers 247 services and is where new presets come from.
Security
Nothing goes through us. Unseenkey has no server in the path, no account and no telemetry. Your keys go only to the provider you're calling, and the desktop app checks GitHub for updates. SECURITY.md lists everything that leaves your machine, and the known open issues.
Vault: Argon2id → XChaCha20-Poly1305, one SQLite file, keys locked in memory and zeroised on lock, 24-word recovery phrase, optional Windows Hello.
Fail closed: each secret is locked to its provider's hosts; unmatched requests, browser-origin requests and anything the broker cannot classify are refused.
Audit: hash-chained log with a keyed head, so usk log verify catches edits, gaps, a log cut short and a deleted head; the entry is committed before the response reaches the caller.
Scrubbing: the real key, its encodings and OAuth access tokens are removed from responses, logs and error messages. The broker negotiates compression itself and unpacks replies before scrubbing; a reply it cannot unpack is refused.
Owner confirmation: revealing a value, approving a request, enrolling a device unlock, loosening a setting and handing out or changing a policy need an owner token that only an unlock or a fresh password or Windows Hello check gives out. It lives in the CLI's or the app's memory, never on disk. The session token in daemon.token, which any program running as you can read, is not enough for them.
Nothing old stays behind: a replaced or deleted value, policy or handle state is erased from the file, not merely superseded.
What it does not do. It stops accidental leaks (chats, git, logs, screenshots, SDK telemetry) and bounds what a dishonest holder of a handle can do. A process running as you with arbitrary code execution can still use an unlocked vault within the care level, add keys, and make care-level handles, and a transparent proxy for tools like gh and git is not built yet. For a hostile agent you also want an OS sandbox. Read the threat model before trusting it with anything; report vulnerabilities privately per SECURITY.md.
Documentation and roadmap
docs/00-README.md indexes the design: vision, decision records, product spec, threat model, architecture, cryptography, broker and policy, data model, API/CLI/MCP reference, implementation plan with as-built notes, testing, operations, UX.
Next is delegation: grant a developer or agency the use of a key with a policy, an expiry, a signed log and a broker they do not control; revoke in one click. Then importers (1Password, Bitwarden, OS keychains), agent-framework plugins, a transparent proxy mode for CLIs, macOS Touch ID, and an attested hosted broker. Order and status in docs/11.
Building and contributing
cargo test --workspace # core, daemon, CLI
cargo install --path crates/usk # puts `usk` and `uskd` on your PATH from this checkout
cd apps/desktop && npm install && npm run tauri dev
See CONTRIBUTING.md. Apache-2.0 for the core, CLI, daemon and desktop app; cloud services, when added, will be AGPL-3.0.
Unseenkey is built by one maintainer. Sponsoring it pays for a first external security audit, code-signed installers and the time to keep fixing security issues quickly.