Your API keys don't belong in your agent's context window.
keygrant is a secrets manager for AI coding agents. The model sees names. The process gets values. You approve every use.
Anything in context can leak
Agents read untrusted input all day — web pages, issues, READMEs, tool results. One injected instruction can make a model emit whatever its context holds: into a URL, a tool call, generated code. Context is also logged, stored by observability tools, and shared in transcripts. If the key is in there, every output channel is an exfiltration channel.
The fix isn't to be careful. It's architectural:
How it works
OS-native storage
DPAPI on Windows, Keychain on macOS, Secret Service on Linux. Never a dotfile, never pasted into chat.
Injection via MCP
exec_with_secrets runs commands with values injected into
that child process only — and redacts output before the model sees it.
You approve each use
Native dialog shows the exact command. Grants last 15 minutes, bound to the requesting agent session. Timeout = deny.
No store tool, by design
The agent can't write secrets either — a value in a tool call would be a value in context. Values enter out-of-band only.
Install
pip install keygrant # or: uv tool install keygrant keygrant init # wires .mcp.json + CLAUDE.md in your project echo "sk-..." | keygrant set STRIPE_KEY --desc "stripe, test mode"
What it doesn't protect against
- An approved command can still exfiltrate. The dialog shows the full command — reading it is the control. Per-secret egress allowlists are on the roadmap.
- Redaction is a second line, not a guarantee. The primary guarantee is that values never enter context.
- Local malware is out of scope. keygrant scopes what agents can touch; it is not an anti-malware product.
Roadmap
- Resident tray app — approval history, one-click revoke
- Per-secret egress allowlists — a key only usable against its API
- Cloud sync & phone approvals — zero-knowledge: the server stores ciphertext it cannot decrypt, and relays verdicts it cannot forge