We use Cursor daily. The completions are fast, inline chat saves real time, and we're not switching away from it. But after a few months of using it across production projects, we noticed something worth paying attention to: Cursor indexes your entire workspace. Every file. Including your .env.
That means your API keys, database passwords, and tokens are in the index. They can show up in suggestions, completions, and conversations with the model. It's not a bug — it's how workspace indexing works. You just need to know about it.
How Cursor accesses your files
Two things are happening under the hood, and both matter for secrets.
Workspace indexing. When you open a project, Cursor scans every file in your workspace — source code, configs, docs, and .env files. This powers the codebase-aware completions and semantic search. It indexes file contents, not just names. That's what makes it useful. It's also what makes plaintext secrets risky.
Context window inclusion. When you ask Cursor something or trigger a completion, it picks relevant files from the index and includes them in the prompt. If your .env looks relevant — and it often does when you're working on config or debugging auth — those values go straight into the context window.
This isn't like a text editor that just displays files. Cursor actively reads, indexes, and sends file contents to a model. Your .env isn't sitting on disk — it's being processed.
What .cursorignore does — and doesn't do
Cursor has a .cursorignore file that works like .gitignore. Drop it in your project root and list what Cursor should skip:
# .cursorignore
.env
.env.*
*.pem
secrets/
Use it. It helps. But know the limits:
- It only covers Cursor. Claude Code, Copilot, Windsurf — none of them read
.cursorignore. Your.envis still wide open to everything else. - Nothing gets encrypted. Your secrets are still plaintext on disk. Any process running as your user can read them — malicious npm packages, VS Code extensions, rogue scripts in
node_modules. - You have to remember. Every new project, every new sensitive file needs an ignore rule. Miss one and the index picks it up. No safety net.
- It doesn't clear what's already indexed. If Cursor indexed your
.envbefore you added the ignore rule, those values may still be cached. You'd need to rebuild the index.
Think of .cursorignore as a seatbelt, not a roll cage. It reduces risk within Cursor. It doesn't solve the real problem: your secrets are plaintext files on disk with zero access control.
Why moving secrets off disk beats ignore rules
Every ignore-based approach — .cursorignore, .gitignore, .copilotignore — works the same way: the secret stays on disk and you trust each tool to skip it. You're playing defense across every tool, every project, every file.
There's a simpler model. No file, no problem.
If your secrets aren't in a file in your project directory, there's nothing for Cursor to index. Nothing for Claude Code to cat. Nothing for a malicious package to scan. The attack surface drops to zero — not because you configured every tool correctly, but because the target doesn't exist.
On macOS, the Keychain is right there. Hardware-encrypted, backed by the Secure Enclave, requires Touch ID to access. Your secrets go from a plaintext file any process can read to an encrypted store that requires biometric auth. That's a category shift, not an incremental improvement.
# The old way: secrets in a file Cursor indexes
$ cat .env
STRIPE_KEY=sk_live_51Hx...
DATABASE_URL=postgresql://admin:secret@...
# The new way: secrets in the Keychain, no file on disk
$ noxkey import myorg/project .env
✓ Imported 5 secrets
$ rm .env
# Load when needed — Touch ID required
$ eval "$(noxkey get myorg/project/STRIPE_KEY)"
No .env file means nothing to ignore. .cursorignore becomes unnecessary for secrets because there are no secret files.
Setting up NoxKey with Cursor
Here's the workflow we use. Five minutes to set up, then you don't think about it again.
Step 1: Install NoxKey
Download NoxKey from noxkey.ai.
Step 2: Import your existing secrets
# Import from your current .env
$ noxkey import myorg/project .env
✓ Imported 5 secrets
# Verify they're there
$ noxkey ls myorg/project/
myorg/project/STRIPE_KEY
myorg/project/DATABASE_URL
myorg/project/OPENAI_API_KEY
myorg/project/CLOUDFLARE_TOKEN
myorg/project/JWT_SECRET
# Peek to confirm values (shows first 8 chars)
$ noxkey peek myorg/project/STRIPE_KEY
sk_live_...
Step 3: Delete the .env file
$ rm .env
This is the step that actually protects you. The import alone isn't enough — as long as the .env exists, it's a target.
Step 4: Load secrets when you start working
# Unlock your project session (one Touch ID for the session)
$ noxkey unlock myorg/project
✓ Session unlocked
# Load the secrets you need
$ eval "$(noxkey get myorg/project/STRIPE_KEY)"
$ eval "$(noxkey get myorg/project/DATABASE_URL)"
# Start your dev server — process.env works as normal
$ npm run dev
That's it. Open a terminal, unlock, load, work. Cursor never sees the raw values because there's no file to index.
How process-tree detection works with Cursor
This is the part we think is neat. Cursor has a built-in terminal and can run shell commands — just like Claude Code. When Cursor's agent runs noxkey get, the process tree looks like this:
└─ Cursor ← Electron app (MATCH)
└─ node ← Cursor runtime
└─ zsh ← spawned shell
└─ noxkey ← get myorg/project/STRIPE_KEY
NoxKey walks the process tree from noxkey up to launchd, checking each ancestor against known AI agent signatures. When it finds cursor in the chain, it switches to restricted mode automatically.
Here's what happens:
- The secret gets encrypted with a one-time AES-256-CBC key
- Written to a self-deleting temp script (
chmod 0600, 60-second TTL) - NoxKey returns
source '/tmp/noxkey_abc123.sh' - Cursor's shell runs the source command — the secret loads into the environment
- The temp file deletes itself
The secret reaches process.env.STRIPE_KEY and your code works normally. But the raw value never appeared in Cursor's context window. It flowed through the OS, not through the chat. Cursor's agent can use the key — it just can't see it.
Compare that to a .env file: the raw value enters the index, gets included in prompts, and sits in the conversation where it can be logged, echoed, or suggested in completions.
The detection is automatic. Nothing to configure, no flags to set. NoxKey checks the process tree on every get call. Full breakdown of all five protection layers here.
What about Cursor's built-in terminal?
Cursor's integrated terminal runs commands as child processes of the Cursor app. Two things to know:
When you type commands manually in Cursor's terminal — running npm run dev or noxkey get yourself — NoxKey still detects Cursor in the process tree. You'll get the encrypted handoff, same as if the agent ran it. We can't distinguish between "human typing in Cursor's terminal" and "Cursor's agent running a command," so we treat both as agent context. Conservative, but safe.
Want the raw value? Use a separate terminal — Terminal.app, iTerm2, anything outside Cursor. NoxKey sees a clean process tree and returns the value directly.
When Cursor's agent runs commands — through inline chat, composer, or the agent panel — the detection works exactly as designed. Encrypted handoff, secrets stay out of the context window, and your API keys don't end up in Cursor's conversation logs.
The full defense stack
Here's what the complete setup looks like — .cursorignore as a belt, NoxKey as the suspenders:
# .cursorignore (still useful for non-secret sensitive files)
*.pem
*.key
credentials/
*.local
# But the real protection:
# 1. Secrets live in the Keychain, not in files
# 2. No .env file exists to ignore
# 3. Process-tree detection handles Cursor automatically
# 4. DLP guard catches any secrets that leak into output
Install the DLP guard as an extra safety net:
$ noxkey guard install
The guard scans tool output for leaked secret values using 8-character fingerprints. If a secret shows up in output — from a log, a debug trace, an inherited env var — the guard catches it before it enters the conversation.
Frequently asked questions
- Does Cursor index my .env file?
- Yes. Cursor indexes all files in your workspace for AI features — completions, search, chat. If your
.envisn't in.cursorignore, its contents are in the index and can end up in prompts. The fix: don't have a .env file. Move secrets to the Keychain and delete it. - Is .cursorignore enough to protect my API keys?
- It helps, but no.
.cursorignoreonly prevents Cursor from indexing specific files. It doesn't encrypt anything, doesn't protect against other tools (Claude Code, Copilot), and relies on you remembering to add every sensitive file. Use it for defense in depth, but don't lean on it alone. Better alternatives exist. - Can Cursor's AI agent still use my secrets for API calls and testing?
- Yes. When Cursor's agent runs
eval "$(noxkey get myorg/project/STRIPE_KEY)", the secret loads into the shell environment via encrypted handoff. The agent can make API calls, run tests, and debug integrations — it just can't see the raw value. It writesprocess.env.STRIPE_KEYin code because that's the only interface it knows. - Does NoxKey work with Cursor's Composer and inline chat?
- Yes. Any command Cursor runs — Composer, inline chat, agent panel — goes through a child process of the Cursor app. NoxKey detects
cursorin the process tree and applies encrypted handoff automatically. No configuration needed. More on how the five protection layers work together. - I use both Cursor and Claude Code — do I need separate setups?
- No. NoxKey's process-tree detection recognizes both Cursor and Claude Code (and Copilot, Windsurf, Cody, Aider, and others). The same
noxkey getcommand works from any tool — the detection layer figures out who's calling and responds accordingly. One setup, every agent covered.
.env files, they're in the index. .cursorignore helps but only covers Cursor and still leaves plaintext on disk. The real fix: move secrets to the macOS Keychain with NoxKey, delete the .env files, and let process-tree detection handle the rest. Your secrets work. They just never enter the conversation.
Free. No account. No cloud. Works with Cursor, Claude Code, and every other AI coding tool on your machine.