I was debugging a Stripe integration at 1am when Claude helpfully printed my live API key in its debug output. Full key. Right there in the conversation log. I stared at it, rotated the key, and thought: this is going to keep happening.
Not because Claude is malicious. Because the system is broken. My secret was in a .env file. The agent read the file. The agent included the value in its response. That's what agents do — they read project files and use what they find. The .env file was the vulnerability, not the agent.
That night I started building NoxKey.
What NoxKey is
A macOS menu bar app and CLI that stores your 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, NoxKey detects it automatically and delivers the value through an encrypted handoff — the secret reaches the agent's process environment without ever appearing in its conversation context.
Architecture: two components, one socket
NoxKey has two pieces:
The menu bar app — a native SwiftUI application that lives in your menu bar. It manages the Keychain, handles Touch ID prompts, performs process-tree agent detection, and serves requests over a Unix domain socket. This is the server. It has Keychain entitlements, biometric access, and full control over what gets returned to whom.
The CLI — a Swift command-line tool (noxkey) that talks to the menu bar app over that Unix socket. It's the interface you use in your terminal. It doesn't touch the Keychain directly — every request goes through the server, which validates the caller independently.
Why a Unix socket instead of XPC or HTTP? Unix sockets give us LOCAL_PEERPID — the kernel tells the server exactly which process connected. No authentication tokens to manage. No port conflicts. No network exposure. The socket file lives at a user-specific path and is accessible only to your user account.
Install in 30 seconds
$ brew install no-box-dev/noxkey/noxkey
==> Downloading noxkey-0.6.43.tar.gz
==> Installing noxkey
==> Caveats
NoxKey menu bar app installed to /Applications.
CLI installed to /usr/local/bin/noxkey.
==> Summary
/Applications/NoxKey.app
/usr/local/bin/noxkey
Launch NoxKey.app from your Applications folder. It appears in the menu bar — a small key icon. That's the server running. The CLI works immediately.
$ noxkey --version
noxkey 0.6.43
No account creation. No master password. No onboarding wizard. It uses your existing macOS login Keychain and your existing fingerprint.
Workflow 1: Import from .env
If you're like I was — 47 .env files scattered across your machine — the first thing you'll do is import them.
$ noxkey import myorg/api .env
[Touch ID prompt]
Imported 6 secrets:
myorg/api/STRIPE_KEY
myorg/api/DATABASE_URL
myorg/api/REDIS_URL
myorg/api/CLOUDFLARE_TOKEN
myorg/api/SENDGRID_KEY
myorg/api/JWT_SECRET
$ noxkey ls myorg/api/
myorg/api/CLOUDFLARE_TOKEN
myorg/api/DATABASE_URL
myorg/api/JWT_SECRET
myorg/api/REDIS_URL
myorg/api/SENDGRID_KEY
myorg/api/STRIPE_KEY
$ rm .env
Secrets are organized as org/project/KEY. One secret, one location, accessible from any terminal in any project directory. No more duplicating the same Cloudflare token across six repos.
Workflow 2: Daily usage with eval
The core pattern is one line:
$ eval "$(noxkey get myorg/api/STRIPE_KEY)"
[Touch ID prompt]
$ echo $STRIPE_KEY
sk_live_... # available in your shell environment
Touch ID fires. The secret loads into your shell's environment. Your script or application reads it from $STRIPE_KEY like it would from any environment variable.
noxkey unlock myorg/api once with Touch ID. All subsequent get calls under that prefix skip biometric auth for a configurable window. The session is bound to your PID and process start time, so PID recycling can't hijack it.
For batch operations — say you need five secrets to run your dev server — session unlock eliminates the fingerprint-per-key friction:
$ noxkey unlock myorg/api
[Touch ID prompt — once]
Session unlocked for myorg/api/* (expires in 15 minutes)
$ eval "$(noxkey get myorg/api/STRIPE_KEY)" # no Touch ID
$ eval "$(noxkey get myorg/api/DATABASE_URL)" # no Touch ID
$ eval "$(noxkey get myorg/api/REDIS_URL)" # no Touch ID
One fingerprint, then flow. The session is bound to your process ID and its start time — PID recycling can't hijack it.
For your most sensitive secrets, strict mode overrides sessions:
$ noxkey strict myorg/api/STRIPE_KEY
# This key ALWAYS requires Touch ID, even during an active session
Workflow 3: Agent detection in action
Here's what happens when Claude Code runs the same command. You don't configure this. It's automatic.
└─ zsh PID 61020 — spawned shell
└─ node PID 58401 — Claude Code runtime
└─ claude PID 58399 — MATCH! Agent detected
Encrypted Handoff ← AES-256-CBC → temp script → source → self-delete
Result: $STRIPE_KEY in shell env. Raw value never in conversation context.
The agent can make API calls. It can run your test suite. It can deploy your app. It just can't see, log, or echo the raw secret value. If it tries to use --raw or --copy, the CLI blocks it with a clear error message.
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.
Features by category
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 updates check, no sync. Your secrets never leave your machine.
Strict mode
High-value secrets always require Touch ID, even during unlocked sessions.
DLP guard
Scans text for leaked secret values using 8-character fingerprints. Configure as a post-tool-use hook to block leaks before they enter AI context.
Developer experience
One command
eval "$(noxkey get org/proj/KEY)"
Session unlock
One Touch ID, then batch operations flow without interruption.
.env import
noxkey import org/proj .env migrates everything in one step.
Peek
noxkey peek org/proj/KEY shows the 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.
Agent safety
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.
Command blocking
--raw, --copy, load, export, bundle, env are all blocked for agent callers.
DLP scanning
Catches leaked values in agent output before they persist.
What NoxKey is NOT
I want to be direct about scope, because knowing what a tool doesn't do is as important as knowing what it does.
Not a team tool. NoxKey is for individual developers. There's no shared vault, no role-based access, no audit log for your team. If you need team secret management, look at Doppler or HashiCorp Vault.
Not cross-platform. macOS only. The entire security model depends on the macOS Keychain, Touch ID, and the Secure Enclave. These don't exist on Linux or Windows. The concepts are portable — but this implementation isn't.
Not a password manager. NoxKey manages developer credentials — API keys, tokens, database URLs, webhook secrets. It doesn't autofill browser forms, generate passwords, or sync across your phone and laptop. Use 1Password or Bitwarden for that.
No cloud sync. Your secrets exist on one machine. If your laptop dies, you need to re-import. This is a feature, not a limitation — it means there's no server to breach, no sync protocol to exploit, no third party that has your data. But it does mean backups are your responsibility.
Why I built this
I was using .env files like everyone else. I had a .gitignore entry. I thought I was fine.
Then AI coding assistants became part of my daily workflow. Suddenly every project file was 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.
I looked at existing options. 1Password's CLI is solid but requires a subscription and doesn't do agent detection. HashiCorp Vault is designed for infrastructure teams, not solo developers. Doppler is cloud-hosted — my secrets would live on someone else's servers. 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. That's NoxKey.
Get started
brew install no-box-dev/noxkey/noxkey
Free. No account. No cloud. Just your Keychain and your fingerprint.
brew install no-box-dev/noxkey/noxkey and your .env files become obsolete.
Read more about credential hygiene, why the macOS Keychain is underused by developers, or how I migrated 47 .env files.