We were debugging a Stripe integration at 1am when Claude printed a live API key in its debug output. Full key. Right there in the conversation log.
The agent was not malicious. The system was broken. The secret sat in a .env file. The agent read the file and included the value in its response. That is what agents do — they read project files and use what they find. The .env file was the vulnerability, not the agent.
That night we started building NoxKey.
A macOS secrets manager built for developers
NoxKey is a macOS menu bar app that stores secrets in the macOS Keychain, protected by Touch ID. No cloud. No accounts. No subscription. Your secrets live in Apple's encrypted storage on your machine and nowhere else.
When an AI agent requests a secret through NoxKey's built-in MCP server, the value reaches the agent's shell environment via an encrypted handoff — never appearing in the conversation context the agent reasons over.
Architecture: menu bar app + MCP server
NoxKey is one process with two surfaces:
The menu bar app is a native SwiftUI application. It owns the Keychain entitlement, runs Touch ID prompts, presents approval sheets for write operations, and produces the encrypted handoff files agents source to load values into their shell environment. This is the only thing on your system with permission to read or write your secrets.
The MCP server ships inside the app bundle. When you launch NoxKey it registers itself with Claude Code, Cursor, and any other MCP-aware agent on your machine. Agents call tools like noxkey_get, noxkey_show, noxkey_set, noxkey_scan, and noxkey_admin. Every call goes through the menu bar app — the MCP server holds no Keychain entitlements of its own.
This split keeps the trust boundary tight. The agent never touches the Keychain. It cannot be tricked into reading a value by a prompt-injected file, because secret retrieval returns a one-shot handoff path the agent has to source in its shell — the value lands in the process environment, not in the conversation transcript the model is reasoning over.
Install this macOS secrets manager in 30 seconds
Install NoxKey from the Mac App Store. The app installs to your Applications folder and registers its MCP server with Claude Code, Cursor, and other MCP-aware agents on first launch.
Launch NoxKey.app from your Applications folder. It appears in the menu bar — a small key icon. That is the server running. No account creation, no master password, no onboarding wizard. It uses your existing macOS login Keychain and your existing fingerprint.
Replace your .env files with Keychain storage
If you have dozens of .env files scattered across your machine, the first step is importing them. Open NoxKey from the menu bar and drop a .env file onto the import sheet. NoxKey shows you every key it found (values masked) and writes the approved batch to the Keychain in a single Touch ID. Then delete the .env.
From an agent — same flow, two MCP calls. noxkey_scan reads the keys without ever sending values into the conversation. noxkey_admin(action: "import", …) raises the same native review sheet so you confirm and unlock the batch:
// Agent-side — values are never returned to the model
noxkey_scan(path: "~/code/api", suggested_org: "myorg", suggested_project: "api")
noxkey_admin(action: "import", entries: […])
// → Review sheet opens. You tap Touch ID once. Batch lands in the Keychain.
Secrets are organized as org/project/KEY. One secret, one location, reachable from any terminal in any project directory. No more duplicating the same Cloudflare token across six repos.
Daily usage: Touch ID once, value never in chat
An agent that needs STRIPE_KEY calls one tool:
noxkey_get(account: "myorg/api/STRIPE_KEY")
// → "Run this in Bash: source '/tmp/noxkey-handoff-…sh' — loads $STRIPE_KEY"
The agent runs that source command in its shell. Touch ID fires. The handoff script writes STRIPE_KEY into the agent's process environment, then deletes itself. The raw value never appears in the conversation transcript — not in arguments, not in tool output, not in any string the model can echo back.
session: "4h" to noxkey_get when an agent will need a chain of related secrets — running a test suite, deploying, or working through a long task. The first call takes Touch ID once; follow-up reads under the same workspace skip biometric auth for the window you set. The session is bound to the calling process, so it cannot be hijacked by an unrelated tool that happens to grab the same PID later.
For high-value keys, mark them strict and they always require Touch ID, even inside an active session — Stripe live keys, production database passwords, anything you would not want unlocked-by-default.
Why the agent never sees the value
The MCP path is the agent identity. When Claude Code or Cursor calls noxkey_get, the menu bar app already knows the request is coming from an agent — that is what the MCP transport is. There is no detection step, no heuristic, no spoofing surface. The response is shaped accordingly: a path to a one-shot handoff script, not the secret itself.
└─ MCP server forwards to menu bar app
└─ Menu bar app Touch ID → ChaChaPoly handoff → /tmp/…sh
└─ Agent shell source /tmp/…sh → $STRIPE_KEY in env, file self-deletes
Result: $STRIPE_KEY in shell env. Raw value never in conversation context.
The agent can make API calls, run your test suite, and deploy your app. It just cannot see, log, or echo the raw secret value. The MCP server enforces this from the response side — there are no --raw or export tools to call, and the handoff file self-deletes the moment it is sourced.
The six most common agent leak patterns — reading .env files, echoing secrets in debug output, storing values in conversation logs, hardcoding them in generated code, passing them to spawned processes — are all mitigated by this approach. For non-MCP callers (a script you wrote, a build hook, a random shell command), the menu bar app falls back to walking the process tree to recognise an agent runtime in the parent chain and route the same handoff response.
Security, DX, and agent safety features
Security
Touch ID on every access
Not a password, not a PIN. Your fingerprint. Every time.
macOS Keychain storage
Apple's Data Protection Keychain, backed by the Secure Enclave. Not a custom vault.
Zero network connections
NoxKey never phones home. No telemetry, no sync. Your secrets never leave your machine.
Strict mode
High-value secrets always require Touch ID, even during unlocked sessions.
Agent guardrails
Every noxkey_get response tells the model not to echo, cat, printenv, or hardcode the value. The MCP server's system instructions repeat the rule.
Developer experience
One MCP call
noxkey_get(account: "org/proj/KEY") — value lands in the agent's shell env, never in chat.
Session unlock
One Touch ID, then a chain of related secret reads flow without interruption.
.env import
Drop the file onto the menu bar app — review keys, one Touch ID, done.
Verify, don't expose
noxkey_show(account: "org/proj/KEY") — first 8 characters for verification, without exposing the full value.
Org/project hierarchy
Secrets are namespaced, searchable, and never duplicated across projects.
Menu bar UI
Browse, add, edit, and organize secrets without touching the terminal.
AI agent security
Automatic agent detection
Process-tree walking identifies Claude, Cursor, Codex, Windsurf, Copilot, and others.
Encrypted handoff
Agents get secrets in their process environment, never in conversation context.
No raw-value tools
The MCP server has no --raw, export, or "echo this secret" tool. The only retrieval path is the encrypted handoff.
Send a secret to a teammate without a server
Storing your own secrets is half the problem. The other half is handing one to a teammate — sending Stripe live keys to a contractor, onboarding a new hire to a project, recovering a credential a co-founder needs at 11pm. The usual options are bad: Slack DMs, password managers that require a shared vault, or the dreaded "I'll text it to you."
NoxKey ships an end-to-end-encrypted share. Right-click any secret, pick a recipient, and NoxKey produces a single .noxkey file. You hand that file off through whatever channel you already trust — iMessage, AirDrop, Signal, email — and the recipient double-clicks it to open the secret in their NoxKey, with their Touch ID, into their Keychain. No server, no account, no shared vault.
The file ships with a per-share content key and a SHA-256 envelope hash that NoxKey burns the moment the recipient opens it — so the same file cannot be re-opened from someone else's machine if the channel leaks. For higher-risk handoffs, choose the Medium tier and the content key is wrapped under a passphrase you tell the recipient out-of-band (PBKDF2-SHA256, 600,000 iterations). A leaked .noxkey file alone is then opaque ciphertext.
What NoxKey does not do
Not a team tool. NoxKey is for individual developers. No shared vault, no role-based access, no audit log. For team secret management, look at Doppler or HashiCorp Vault.
Not cross-platform. macOS only. The security model depends on the macOS Keychain, Touch ID, and the Secure Enclave. These do not exist on Linux or Windows. The concepts are portable — this implementation is not.
Not a password manager. NoxKey manages developer credentials — API keys, tokens, database URLs, webhook secrets. It does not autofill browser forms or sync across devices. Use 1Password or Bitwarden for that.
No cloud sync. Your secrets exist on one machine. If your laptop dies, you re-import. This is a feature — no server to breach, no sync protocol to exploit, no third party with your data. Backups are your responsibility.
Why we built a dotenv alternative for macOS
We were using .env files like everyone else. We had a .gitignore entry. We thought we were fine.
Then AI coding assistants became part of the daily workflow. Every project file became fair game for an agent to read, reference, and include in responses. The .env file went from "slightly risky convenience" to "active liability." The dotenv pattern was designed in 2012, before AI agents existed. It assumes the only thing reading your project files is your code.
We looked at existing options. 1Password CLI is solid but requires a subscription and has no agent detection. HashiCorp Vault targets infrastructure teams, not solo developers. Doppler is cloud-hosted. None of them distinguish between a human caller and an AI agent.
The macOS Keychain was sitting right there. Encrypted. Biometric. Local. Already on every Mac. All it needed was a developer-friendly interface and awareness of AI agents.
Get started
Free. No account. No cloud. Your Keychain and your fingerprint.
Read more: how we migrated 47 .env files, how Touch ID protects your API keys, or six ways AI agents leak secrets.
Frequently asked questions
- What is NoxKey?
- NoxKey is a free, open-source macOS app that stores developer secrets (API keys, tokens, passwords) in the macOS Keychain with Touch ID. It replaces .env files with hardware-encrypted storage and adds AI agent detection with encrypted handoff.
- How does NoxKey detect AI agents?
- NoxKey walks the macOS process tree when a secret is requested. If it detects an AI agent (Claude Code, Cursor, Copilot) in the calling chain, it switches to encrypted handoff — the secret reaches the agent's shell environment through a self-deleting encrypted script, never entering the conversation context.
- Is NoxKey free?
- Yes. NoxKey is AGPL-3.0 open source and completely free. No account, no subscription, no cloud. Install from the Mac App Store.
- How do I migrate from .env files?
- Drag the
.envfile onto the import sheet in the menu bar app — every key/value is shown for review (values masked) and the approved batch is written to the Keychain under one Touch ID. Then delete the.envfile. Agents access secrets afterwards via the MCP tool:noxkey_get(account: "myorg/myproj/KEY")returns asourcecommand that loads the value as an env var without it ever entering the conversation. - Does NoxKey send data to the cloud?
- No. NoxKey makes zero outbound network connections. All secrets are stored locally in the macOS Keychain, which uses Apple's Secure Enclave for hardware encryption. This is verifiable via macOS network monitoring.
- What's the difference between NoxKey and 1Password CLI?
- NoxKey is local-only (no cloud, no account), free, and includes AI agent detection with encrypted handoff. 1Password CLI requires a cloud subscription and has no AI-specific security features. Full comparison.