Rightshold™ Sign up

Answers · agent safety

How do I keep .env secrets and API keys away from an AI coding agent?

Short answer: Assume anything the agent can read can end up in its context, its logs, a commit or a tool call, and give it only what it needs. Block the files in the agent's own controls (in Claude Code, Read deny rules such as Read(./.env), Read(./.env.*) and Read(./secrets/**) in .claude/settings.json; in Cursor, .env files are ignored by default and .cursorignore adds more), but know those controls cover the agent's file tools, not every program it runs: Claude Code's docs say deny rules don't stop a script that opens files itself, and Cursor's say terminal commands and MCP tools run outside its file access controls. So the real fixes are outside the prompt: keep production secrets off the machine the agent works on, give the agent development keys with low limits, load real secrets at run time from a secret manager, turn on OS-level sandboxing, and scan commits for secrets before they leave.

Checklist

  1. Block secret files in the agent's settings. Claude Code: add "Read(./.env)", "Read(./.env.*)" and "Read(./secrets/**)" to permissions.deny in .claude/settings.json (a .claudeignore file has no effect). Cursor: .env files are ignored by default; add other secret paths to .cursorignore.
  2. Turn on OS-level enforcement where the tool offers it. Claude Code's sandbox enforces sandbox.filesystem.denyRead paths (for example ~/**/.env) for every sandboxed command and its child processes, so a Python or Node script can't read the file either. By default the sandbox still lets commands read most of the machine, so list the secret paths.
  3. Keep production credentials off the agent's machine or container entirely. Use separate development keys with low spending limits, test-mode payment keys and a non-production database, so a leaked key costs little and is easy to rotate.
  4. Inject secrets at run time instead of writing them to files: a secret manager CLI (for example 1Password's op run, Doppler or Infisical) passes them to the process that needs them, so there is no .env file to read. Remember the running process, and any agent that can run it, still sees them.
  5. Don't paste keys into chat, CLAUDE.md, rules files or MCP server configs that get committed. Reference an environment variable instead, and keep .env and .env.* in .gitignore.
  6. Give MCP servers and agents scoped tokens: read-only where possible, limited to one repository or project, short-lived, and separate per tool, never your personal admin key.
  7. Catch leaks before they leave: run a secret scanner such as gitleaks as a pre-commit hook and in CI, and turn on GitHub secret scanning with push protection so a commit containing a known key format is blocked at push.
  8. If a key was exposed to the agent, rotate it. Deleting it from the chat or the file doesn't remove it from transcripts, logs or anything the agent already sent.

Why ignore rules aren't enough

Where secrets usually leak

Ask Rightshold (free, no key)

Add the MCP server https://www.rightshold.com/mcp to Claude, Cursor, ChatGPT, Grok or VS Code, then ask: “Before I give this MCP server an API token, is it a listed server, what tools does it expose, and have its tool definitions changed?”

One-click setup

{
  "tool": "precall_check",
  "arguments": {
    "url": "<the MCP server's https URL>"
  }
}

Rightshold does not read your files, manage your secrets or scan your repository for keys; secret handling lives in your agent's settings, your secret manager, your sandbox and your CI.

Sources

Related

Not legal advice. Updated 2026-10-29. JSON · Markdown · All answers

Get a free API key in one call

No card and no email needed. 100 free credits; the license and policy checks stay free without a key.

curl -s -X POST https://www.rightshold.com/v1/accounts/signup -H "Content-Type: application/json" -d '{"accept_terms":true}'
export RIGHTSHOLD_API_KEY=rs_...   # the api_key from the reply (shown once)
curl -s https://www.rightshold.com/v1/licenses/check -H "Authorization: Bearer $RIGHTSHOLD_API_KEY" \
  -H "Content-Type: application/json" -d '{"license":"MIT","intended_use":{"commercial_use":true}}'