Skip to content
All writing

How to Protect .env Files and API Keys in Cursor

Protect .env files and API keys in Cursor with .cursorignore and file and shell hooks. Keep secrets out of indexing and AI context.

#snippetsdev-toolssecurityai

To protect .env files and API keys in Cursor, exclude secrets from indexing and gate file and shell access with hooks. .cursorignore does not restrict terminal commands or MCP tools.

Add this to your project's .cursorignore. Keep examples free of real credentials.

.env
.env.*
!.env.example
!.env.template
!.env.sample
.dev.vars*
*.pem
*.key
credentials.json
secrets.json

Create .cursor/hooks/guard-env.py:

import json
import os
import re
import sys

try:
    data = json.load(sys.stdin)
except Exception:
    print(json.dumps({"permission": "deny"}))
    sys.exit(0)

safe = {".env.example", ".env.template", ".env.sample", ".env.defaults"}
value = data.get("file_path", "") + " " + data.get("command", "")
tokens = re.findall(r"[^\s\"';&|<>()]+", value)
blocked = False
for token in tokens:
    name = os.path.basename(token)
    if name in safe:
        continue
    if (name == ".env" or name.startswith(".env.") or name == ".envrc"
        or name.startswith(".dev.vars")
        or name.endswith((".pem", ".key", ".p12", ".pfx"))
        or name in {"id_rsa", "id_ed25519", "credentials.json", "secrets.json"}
        or re.search(r"(?:^|/)(?:\.ssh|\.aws|\.gnupg)(?:/|$)", token)):
        blocked = True
if re.search(r"\bprintenv\b|(?:^|[\s;&|])env\s*(?:$|[;&|])", value):
    blocked = True

print(json.dumps({
    "permission": "deny" if blocked else "allow",
}))

Merge this into .cursor/hooks.json, preserving existing hooks. Project hook commands run from the project root.

{
  "version": 1,
  "hooks": {
    "beforeReadFile": [
      { "command": "python3 .cursor/hooks/guard-env.py", "failClosed": true }
    ],
    "beforeTabFileRead": [
      { "command": "python3 .cursor/hooks/guard-env.py", "failClosed": true }
    ],
    "beforeShellExecution": [
      { "command": "python3 .cursor/hooks/guard-env.py", "failClosed": true }
    ]
  }
}

Test dummy .env reads, cat .env, printenv, and permitted .env.example reads. This catches recognized paths and commands; indirect shell reads and MCP access need separate controls. Keep production secrets outside the agent's workspace and shell environment.

See Cursor's hook contract and ignore-file limitations. For other tools, read how to keep sensitive files out of AI coding agents.

Get new posts by email

New writing in your inbox. Unsubscribe anytime.