Skip to content

Agents and multimodal systemsGuide

AI coding agents and secrets: how keys leak and how to stop it

A coding agent reads files, runs commands and writes a transcript of everything it saw. That puts your .env file, your shell's environment and your MCP configuration within reach. Here is where secrets leak in agent workflows, and the controls Claude Code and Cursor actually document.

By INFRO Editorial

Published

8 min read

A stack of translucent amber glass layers on a dark ground with small points of light drifting through them

In short

Coding agents can read .env files, inherit secrets from the shell environment, store what they read in plaintext transcripts, and commit keys they were shown. Claude Code lets you deny reads of .env with permission rules and block credential files and variables with its OS-level sandbox; Cursor's .cursorignore blocks files from Agent and Tab but not from its terminal or MCP tools. Add environment separation, short-lived or low-limit keys, prompt guardrails that detect API keys, and give agents a gateway key instead of a raw provider key.

Key takeaways

  • Agents reach secrets four ways: reading files such as .env, inheriting the shell's environment, storing what they saw in plaintext transcripts, and writing keys into code or commits.
  • Claude Code's Read deny rules cover its file tools and the shell commands it recognizes, such as cat; they do not cover a script that opens the file itself, which is what the OS-level sandbox is for.
  • Claude Code writes every tool result to a plaintext transcript; anything an agent reads from .env is on disk until the retention sweep removes it, 30 days by default.
  • Cursor's .cursorignore keeps files from Agent, Tab and @ mentions, ignores .env files by default, and cannot block the terminal or MCP tools.
  • Give agents a gateway key with a spend limit and expiry instead of a raw provider key, and detect API keys in prompts before they reach the provider.

How do AI coding agents expose secrets? A coding agent reads files, runs shell commands and keeps a transcript, so it can reach your .env file, inherit API keys from your shell's environment, write what it read into plaintext logs on disk, send pasted keys to the model provider, and commit a key it was shown. The fixes are mostly configuration you can apply today: deny reads of secret files in the agent's own settings, run its commands in an OS-level sandbox that hides credential files and variables, shorten transcript retention, keep production credentials out of developer environments, and give agents a low-limit gateway key instead of a raw provider key.

This guide covers where secrets leak in agent workflows and what Claude Code and Cursor document to prevent it. The tool-access side of agents is in MCP server credential leaks; routing agent traffic through a gateway is in Claude Code and Codex through a gateway.

Four ways an agent reaches a secret

1. It reads the file

An agent explores the repository to understand it, and .env, config/secrets.yml and credentials.json are files like any other. In Claude Code, reading files inside the working directory needs no approval in the default mode, and a built-in set of read-only shell commands — including cat, head, grep and find — runs without a prompt in every mode1. Nothing malicious is required: an agent debugging a connection error will reasonably open the file that holds the connection string.

2. It inherits the environment

Shell commands an agent runs get the environment of the process that started them. Claude Code's sandbox documentation spells out the default: commands can read "most of the machine, including credential files such as ~/.ssh and ~/.aws/credentials", and environment variables are "inherited from Claude Code, including any secrets in its environment"2. If you export OPENAI_API_KEY=… in your shell profile, every command the agent runs — and every package install script those commands trigger — can read it.

That last part matters. The OSV advisory for the May 2026 "Mini Shai-Hulud" npm campaign describes packages, including two MCP server packages, whose install hook harvested cloud keys, GitHub and npm tokens and SSH keys, and persisted through, among other things, "AI agent session hooks"3. An agent that runs npm install runs that hook with your environment. AI supply chain attacks in 2026 covers the wider pattern.

3. It writes what it saw to disk

Claude Code stores each session as a transcript at ~/.claude/projects/<project>/<session>.jsonl, holding "every message, tool call, and tool result", in plaintext with only OS file permissions as protection; the documentation states that if a tool reads a .env file or a command prints a credential, the value is written to that transcript4. Transcripts are swept after cleanupPeriodDays, 30 days by default, while ~/.claude/history.jsonl keeps every prompt you typed until you delete it4. A key pasted into a prompt therefore lives in your history, in the transcript, and in the request sent to the model provider.

4. It puts the key into code

An agent asked to "make the integration work" may inline the key it found, write it into a test fixture, or add it to a config file that is not ignored. GitGuardian's 2026 report says commits co-authored by Claude Code leak secrets at about twice the baseline rate, and it counts 24,008 unique secrets exposed in MCP configuration files5. Those numbers describe a correlation in public commits, not a defect in one tool, but the direction is clear: more code written faster means more chances to commit a key. Secret scanning and push protection is the backstop for that.

What Claude Code documents

Deny reads of secret files

Claude Code's own settings example denies .env reads6:

~/.claude/settings.json (or .claude/settings.json for the team)
{
  "permissions": {
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)"
    ]
  }
}

Know exactly what these rules cover. Read and Edit deny rules apply to Claude's built-in file tools, to file commands Claude Code recognizes in Bash such as cat, head, tail, sed and tee, and to redirection targets; they do not apply to a command that reads files without naming them, such as grep -r pattern ., or to a Python or Node script that opens files itself1. A .claudeignore file has no effect; move its entries into deny rules1. Bare file names match at any depth, so Read(.env) covers nested .env files under the working directory1.

Enforce it at the OS level with the sandbox

For enforcement that covers every process, Claude Code points to its sandbox1. The sandbox applies OS-enforced limits to Bash, PowerShell and Monitor commands and the processes they start; it runs on macOS, Linux and WSL2, and on native Windows commands run unsandboxed2. Its sandbox.credentials setting denies reads of listed credential files and unsets listed environment variables before each sandboxed command, and there is no built-in credential deny list, so only what you list is protected2:

Sandbox credential rules (user or managed settings)
{
  "sandbox": {
    "enabled": true,
    "credentials": {
      "files": [
        { "path": "~/.aws/credentials", "mode": "deny" },
        { "path": "~/.ssh", "mode": "deny" }
      ],
      "envVars": [
        { "name": "OPENAI_API_KEY", "mode": "deny" },
        { "name": "ANTHROPIC_API_KEY", "mode": "deny" }
      ]
    }
  }
}

The sandbox covers shell commands only: Claude's file tools, MCP servers and hooks run outside it, so you need both the permission rules and the sandbox2. Claude Code applies none of the credentials entries from project or local settings files, so put them in user or managed settings2. To strip credentials from all subprocesses regardless of sandboxing, Claude Code documents CLAUDE_CODE_SUBPROCESS_ENV_SCRUB2.

Make it organization policy

Settings in .claude/settings.json apply to everyone who clones the repository, and deny rules from it apply immediately, without the workspace-trust step that allow rules wait for6. Managed settings, delivered by MDM, a managed-settings.json file or the claude.ai admin console, sit above every other level and cannot be overridden by a developer's own files6. Put the .env deny rules and the sandbox credential list there.

Shorten what transcripts keep

Lower cleanupPeriodDays, set CLAUDE_CODE_SKIP_PROMPT_HISTORY where transcripts are not needed, and use claude purge to delete a project's local state after an incident4.

Keep MCP secrets out of shared files

A team .mcp.json should reference keys as ${API_KEY} rather than contain them; Claude Code expands environment variables in that file, and in a remote server's URL and headers it reads some credential variables as empty so a project's file cannot send your credentials to a server it names7. Personal MCP servers live in ~/.claude.json7, which is one more plaintext file worth knowing about.

What Cursor documents

Cursor's .cursorignore keeps files from Agent, Tab, Inline Edit and @ mention references, and Cursor ignores .env* files, .gitignore entries and a default list automatically8. Two caveats from the same page: "The terminal and MCP server tools used by Agent cannot block access to code governed by .cursorignore", and complete protection "isn't guaranteed"8. Treat it as a convenience that keeps secrets out of context, not as a boundary.

For MCP, Cursor reads .cursor/mcp.json in a project and ~/.cursor/mcp.json globally, supports ${env:NAME} interpolation, and its own recommendations are to use restricted keys with minimal permissions and environment variables for secrets, never hardcoded values9.

Controls that do not depend on the tool

Agent settings can be misconfigured, bypassed by a new tool or simply not deployed on a contractor's laptop. These hold regardless:

  • Keep production credentials off developer machines. An agent can only leak what its environment holds. Production keys belong in the production secret manager, injected at runtime.
  • Give each developer their own key with a low ceiling. A per-developer key with a spend limit and an expiry turns a leak into a bounded, attributable event. Bounding agent loops covers limits for runaway sessions as well.
  • Prefer short-lived credentials. Where the provider supports federation or short-lived tokens, the key in the environment expires in minutes; see short-lived credentials for AI APIs.
  • Detect keys in prompts. A key pasted into a prompt, or read from a file into a tool result, can be caught by a pattern check before the request leaves for the provider.
  • Scan before push. A pre-commit hook catches the key an agent wrote into code.

How INFRO handles coding agent traffic

INFRO lets Claude Code, Codex and the agent SDKs call models through POST /v1/messages and POST /v1/responses with an INFRO gateway key in place of a provider key; setup is in Claude Code & Codex. What that changes for secrets:

  • The developer holds a gateway key, not your provider key. Issue one per developer or per agent, limited to the providers and environment it needs, with a spend limit checked before the provider is called (402 when it cannot cover the request), an expiry, and an optional IP allowlist. Revoking it does not touch your provider account or anyone else's key.
  • Guardrails inspect agent traffic (Business plan). On /v1/messages and /v1/responses they check every text block, tool input and tool result; the secret detector matches OpenAI, Anthropic, Google, AWS access key id, GitHub, Slack, Stripe and INFRO key formats, JWTs and PEM private keys, and can block, redact or flag. It is pattern-based: it misses formats it does not know, such as AWS secret access keys and passwords.
  • The audit log records key changes, and the request log shows spend per key, so a leaked developer key shows up as one key's traffic.

The honest limit: a gateway key in a developer's environment can be read by the agent like any other variable. Its value is that it is bounded — by spend limit, expiry, IP range and environment — and revocable without touching the provider. And INFRO governs only traffic that goes through it; a provider key left in the same shell can be used directly against the provider, so remove raw provider keys from developer environments and keep provider-side limits as the backstop.

Summary

Coding agents reach secrets by reading files, inheriting the environment, recording what they saw and writing keys into code. In Claude Code, deny .env reads, enable the sandbox with credential rules, push both through managed settings and shorten transcript retention; in Cursor, rely on .cursorignore for context but not as a boundary. Then make the keys an agent can see cheap to lose: per-developer gateway keys with limits and expiry, short-lived credentials where providers offer them, guardrails on prompts and a scanner before every push.

Questions readers ask

Can Claude Code read my .env file?
Yes, by default: reading files inside the working directory needs no approval. Add Read deny rules such as Read(./.env) and Read(./.env.*) to settings. They block Claude's file tools and shell commands Claude Code recognizes, such as cat; for scripts that open files themselves, turn on the sandbox and deny the path there too.
Does .cursorignore stop Cursor's agent from reading secrets?
It keeps ignored files from Agent, Tab, Inline Edit and @ mentions, and .env files are on Cursor's default ignore list. Cursor's documentation says the terminal and MCP tools used by Agent cannot be blocked by .cursorignore, and that complete protection is not guaranteed.
Where does Claude Code store what the agent saw?
In plaintext session transcripts under ~/.claude/projects/, which record every message, tool call and tool result. If a tool reads a .env file, the value is in that file. Transcripts are removed after cleanupPeriodDays, 30 by default; prompt history in ~/.claude/history.jsonl is kept until you delete it.
Should a coding agent use my provider API key?
Prefer not. Give the agent a key you can afford to lose: a gateway key per developer with a spend limit, an expiry and an IP allowlist, or a short-lived provider credential. A raw provider key in a developer's environment can be read by the agent, any package it installs and anything else on the machine.

From the team that builds it

Where this shows up in INFRO

INFRO is a control plane in front of the provider accounts you already hold. The capabilities below are the parts of it this article touches, each with the documentation that defines its behaviour.

  • Claude Code and Codex through INFRO

    Available with a plan

    Point Claude Code, the Claude Agent SDK, Codex or the OpenAI Agents SDK at INFRO by changing the base URL and the key. Anthropic's Messages API and OpenAI's Responses API, with routing, budgets refused before the call, guardrails and the request log applied as on every other request.

  • Guardrails

    Available with a plan

    Pattern-based checks on chat completion prompts and responses: block, redact or flag email addresses, phone numbers, card numbers, IBANs, US Social Security numbers, IP addresses, API keys and your own terms, plus optional classifier checks on your own connection to a decision model's provider. Detection can miss things. Included from the Business plan.

    Read the documentation for Guardrails
  • Key limits and rotation

    Available with a plan

    Limit a gateway key to chosen providers or IP ranges, and rotate it with an overlap window so the old key keeps working while you deploy the new one.

    Read the documentation for Key limits and rotation
  • Budgets and spend ceilings

    Available with a plan

    A hard cap per organization, project, member, and key, with alerts at your own thresholds.

    Read the documentation for Budgets and spend ceilings
  • Environments

    Available with a plan

    Production, staging and development to start, and your own beside them. A connection or route serves one, several or every environment; each gateway key belongs to exactly one, and never reaches a connection outside it.

    Read the documentation for Environments
  • Audit log

    Available with a plan

    Member, key, and policy changes recorded with actor and timestamp, viewable in the console.

    Read the documentation for Audit log

INFRO accounts are self-serve. Provider usage is billed to you by your providers; INFRO charges a software subscription and takes 0% of model spend. See plans.

Sources

Numbered in order of first citation. Each was opened and checked against the claim on the date shown.

  1. 1.Configure permissions (opens in a new tab) — Claude Code Docs. Accessed Oct 21, 2026.
  2. 2.Configure the sandboxed Bash tool (opens in a new tab) — Claude Code Docs. Accessed Oct 21, 2026.
  3. 3.MAL-2026-4068: Malicious code in @antv/mcp-server-antv (npm) (opens in a new tab) — OSV. Accessed Oct 21, 2026.
  4. 4.Explore the .claude directory (opens in a new tab) — Claude Code Docs. Accessed Oct 21, 2026.
  5. 5.The State of Secrets Sprawl 2026 (opens in a new tab) — GitGuardian. Accessed Oct 21, 2026.
  6. 6.Settings files and precedence (opens in a new tab) — Claude Code Docs. Accessed Oct 21, 2026.
  7. 7.Connect Claude Code to tools via MCP (opens in a new tab) — Claude Code Docs. Accessed Oct 21, 2026.
  8. 8.Ignore files (opens in a new tab) — Cursor Docs. Accessed Oct 21, 2026.
  9. 9.Model Context Protocol (MCP) (opens in a new tab) — Cursor Docs. Accessed Oct 21, 2026.

About this article

On 2026-10-21 we opened Claude Code's settings, permissions, sandboxing, MCP and .claude directory documentation, Cursor's ignore-file and MCP documentation, GitGuardian's State of Secrets Sprawl 2026 page and the OSV advisory MAL-2026-4068. INFRO behaviour is described from its coding agents and guardrails documentation. Written by the team that builds INFRO.

Last checked against its sources on . The next review is due by . No separate named reviewer is recorded for this article.

How articles are written, sourced and corrected is set out in the editorial standards.