Inter-office memo

To
Everyone who lets a coding agent work in a project with keys in it
From
Mo, Chief Executive
Date
November 9, 2026, 4:44 PM CST
Re
Secrets and coding agents

How to keep API keys and .env secrets from Claude Code and Codex in 2026: 8 ways compared

It depends on the job. To hide a .env file, add a Read deny rule in Claude Code or a deny entry in a Codex permission profile, both free, and turn on the sandbox, because a rule alone doesn’t stop a script. To keep plaintext off your disk, load keys from 1Password, Doppler or Infisical. To let an agent use a key without reading it, use network secrets in the cloud, Docker Sandboxes, or Enjoy’s project secrets.

Disclosure: Enjoy is our product, and it keeps tokens as project secrets. We checked every way below against its maker’s own pages on November 9, 2026, and we say where another way is the better pick, including the free ones built into Claude Code and Codex.

The ways to keep secrets from a coding agent, compared

A coding agent reads your files and runs commands as you. Claude Code’s sandbox docs list what a command can reach even with the sandbox on: “Most of the machine, including credential files such as ~/.ssh and ~/.aws/credentials,” and environment variables “Inherited from Claude Code, including any secrets in its environment.” What an agent reads goes to the model’s maker with the rest of the conversation, and Claude Code keeps “session transcripts locally in plaintext under ~/.claude/projects/ for 30 days by default.”

So keeping keys from an agent is three jobs, and no way below does all three: hiding a file such as .env, keeping the plaintext off your disk, and letting an agent use a key without reading it.

Way Best for Price, checked November 9, 2026 Works with What an agent can still reach
Read deny rules A quick block on .env files Free with Claude Code Claude Code A script that opens the file itself
Claude Code’s sandbox Blocking or masking the credentials you list, for every command Free with Claude Code Claude Code on Mac, Linux and WSL2 Anything you didn’t list
Codex permission profiles Hiding .env files and variables from Codex’s commands Free with Codex; profiles are in beta Codex on Mac, Linux, WSL and Windows Matching files made after a command starts, on Linux, WSL and Windows
1Password Keeping plaintext off your disk, behind an approval prompt Individual $3.99 a month, billed yearly; free for 14 days Any agent; a plugin for Claude Code A mounted .env, once you unlock it
Doppler or Infisical A team’s shared keys, loaded when a command runs Doppler: free for 3 users. Infisical: free for up to 5 identities Any agent The environment of the command it starts
Docker Sandboxes An agent in a microVM that never holds its API keys Free on your own computer Claude Code, Codex and eight more agents The project folder you share with it
Network secrets in the cloud Tasks that call an API with a key the agent can’t read With Claude Pro ($20 a month) and up; Codex on the web comes with ChatGPT Plus ($20) and up Claude Code on the web, Codex Cloud Plain environment variables you add beside them
Enjoy Handing any agent a token by name, with no settings file to write A monthly subscription, free for 7 days (pricing) Claude Code, Codex, Grok Build, Antigravity, Muse Code, OpenCode What a command does with the secret it uses

Prices are per month as each maker lists them, before tax. Claude Code and Codex themselves run on a Claude or ChatGPT plan, or an API key, which those companies bill for separately.

Before you start: what no setting undoes

  • A secret an agent has read is spent. It’s in the transcript and it went to the model’s maker, so replace it with a new one. 1Password’s docs say the same of moving old keys into a vault: it “secures them going forward, but doesn’t mitigate any past exposure, such as in your Git history or your coding agent memory.”
  • A .claudeignore file does nothing. Anthropic’s permissions docs say “If your project has a .claudeignore file, it has no effect, so move its entries into Read deny rules.”
  • Don’t type a key into a prompt or a command. Claude Code’s “Yes, and don’t ask again” saves the approved command, secret included, and Apiiro found that “Out of 104,185 public copies of this file on GitHub, 1,122 hold a real secret.” Its advice: “Reference them as $VAR from whatever secrets manager you use.” Our memo has the steps to check your own repositories.
  • Keep a backstop on git. GitHub’s push protection “blocks pushes that contain secrets before they reach your repository,” whichever way a key got into a file.

Read deny rules in Claude Code

Best for: a quick block on .env files, in every project, in a minute.

Anthropic’s settings docs give the rule themselves. To “stop it reading .env files, add this to ~/.claude/settings.json,” and the part of their example that does it is:

{
  "permissions": {
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)"
    ]
  }
}

A Read deny rule is how you “block Claude’s file tools from reading a file or directory,” and the permissions docs add Read(./secrets/**) as a second example. A bare file name reaches deeper: “Read(.env) and Read(**/.env) are equivalent,” matching “any .env at or under the current directory.”

Price: free with Claude Code.

Watch for: it isn’t a wall. The 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,” but they “don’t apply to a command that reads files without naming them, such as grep -r pattern . run from the directory that holds the file, or to arbitrary subprocesses that read or write files indirectly, like a Python or Node script that opens files itself.” Anthropic names the next step in the same paragraph: “For OS-level enforcement that blocks all processes from accessing a path, enable the sandbox.”

Claude Code’s sandbox

Best for: stopping a script as well as a file tool, and letting a command use a token it can’t read.

With the sandbox on, “the shell commands Claude runs start inside its boundary, and so do the processes they start.” Its sandbox.credentials setting “declares credential files and environment variables to protect from sandboxed commands.” With "mode": "deny", files “are denied for reads inside the sandbox” and “environment variables are unset before each sandboxed command runs.” Anthropic’s example:

{
  "sandbox": {
    "enabled": true,
    "credentials": {
      "files": [
        { "path": "~/.aws/credentials", "mode": "deny" },
        { "path": "~/.ssh", "mode": "deny" }
      ],
      "envVars": [
        { "name": "GITHUB_TOKEN", "mode": "deny" },
        { "name": "NPM_TOKEN", "mode": "deny" }
      ]
    }
  }
}

A project’s .env goes in the same list. In a project’s .claude/settings.json, the settings reference says a ./ path is “Relative to the project root.”

"mode": "mask" goes a step further. Claude Code “shows sandboxed commands a per-session placeholder called the sentinel, and the sandbox proxy substitutes the real value on outbound requests to hosts you allow,” so “The command and anything it logs never hold the real credential, but its requests still authenticate.”

Price: free with Claude Code.

Watch for: “The sandbox is off by default,” and “There is no built-in credential deny list, so only the files and variables you list are restricted.” It “runs on macOS, Linux, and WSL2. On native Windows, Claude Code runs commands unsandboxed.” It wraps shell commands, not Claude’s own file tools: “A denyRead entry doesn’t stop the Read tool,” so keep the Read rules too. Masking needs network.tlsTerminate, which the docs call “experimental,” and “For files on macOS, Claude Code blocks the file instead of masking it.” Anthropic’s own summary: “Sandboxing reduces risk but is not a complete isolation boundary.”

Codex permission profiles

Best for: hiding .env files and secret-looking variables from the commands Codex runs.

Codex’s permission profiles “let you apply least-privilege boundaries to local commands Codex runs on your behalf.” The part of OpenAI’s example that hides the files, in config.toml:

default_permissions = "project-edit"

[permissions.project-edit]
extends = ":workspace"

[permissions.project-edit.filesystem.":workspace_roots"]
"**/*.env" = "deny"

“This rule denies reads for matching .env files found beneath each runtime or profile-defined workspace root,” OpenAI says, for “keeping environment files, generated secrets, or similar credential-bearing files unreadable.” Exact paths work too, “for stable locations such as ~/.ssh.” On Linux, WSL and Windows, an unbounded ** pattern “may need bounded pre-expansion,” set with glob_scan_max_depth.

Environment variables are a separate setting. shell_environment_policy “controls which environment variables Codex passes to spawned commands”: inherit = "core" passes “a trimmed set,” inherit = "none" starts from “an empty environment,” and a filter such as "AWS_*" = "exclude" removes what matches.

Price: free with Codex.

Watch for: the page opens with “Beta. Permission profiles are under active development and may change,” and profiles “do not compose with the older sandbox settings.” If sandbox_mode appears in any loaded config file, “Codex uses those older sandbox settings instead.” On Linux, WSL and Windows, “Matching files created afterward are not added to that process’s deny list,” so “Don’t rely on a glob to block newly created files in that running process.” Profiles “govern sandboxed commands that run on your machine,” while “Connectors, MCP servers, browser or computer-use surfaces” and Codex Cloud “use their own controls.” And the automatic filter for variables is off: “ignore_default_excludes defaults to true, so Codex doesn’t automatically remove variable names containing KEY, SECRET, or TOKEN. Set it to false.”

1Password

Best for: keeping the plaintext off your disk, with a prompt before anything reads it.

It comes in three pieces. op run “runs the provided command in a subprocess with the secrets made available as environment variables only for the duration of the process,” and its reference says “Secrets printed to stdout or stderr are concealed by default.” A mounted .env file puts a file where your app expects one “without actually storing the plaintext contents on your device,” passing it “through a UNIX-named pipe” after you approve a prompt. And its MCP server, which the beta plugin for Claude Code sets up and which lists Codex among its clients, lets an agent create and manage your Environments while it “can only see the names of your secrets and Environments, and never returns the actual secret values.”

Price: the Individual plan is $3.99 a month, billed yearly, or $2.99 for a new customer’s first year during the current promotion, and it’s free for 14 days, per 1Password’s pricing.

Watch for: a mounted file isn’t hidden from an agent. “There’s no distinction made between different processes reading the file. Once the file is unlocked, every process can read it until you lock 1Password or disable the .env file in 1Password.” Mounted files and the MCP server “are currently only supported on Mac and Linux.” And when Claude Code imports an old .env for you, it will “Read the .env file to get its variable names and values,” and 1Password says to “rotate all secrets that were previously stored in plaintext” afterward.

Doppler or Infisical

Best for: a team’s shared keys, loaded into a command when it runs, with nothing in the project folder.

Both replace the .env file with a command. Doppler supplies secrets “via environment variables, using the doppler run command,” as in doppler run -- npm start. For an app that reads a file, “you can mount an ephemeral .env or JSON file,” which is “a Linux named pipe that can be read like a file and is automatically cleaned up when the Doppler process exits.” Infisical’s infisical secrets-manager run will “Inject secrets from Infisical into a process as environment variables.” Infisical also sells Agent Vault for “the AI agents you run in your own infrastructure”: they call APIs “through an Agent Vault proxy, which attaches the real credentials so the agents never see them.”

Price: Doppler’s Developer plan is “Free for 3 users,” then $8 a month for each additional user, and Team is $21 a user a month. Infisical’s Free plan is $0 for “Up to 5 identities,” and Agent Vault is $2 per 1,000 requests, with the “First 5,000 requests/mo free.”

Watch for: doppler run and Infisical’s run hand the real values to the command they start, as its environment variables. That keeps keys out of your folder and out of git, not out of a command an agent runs through them. Agent Vault is the piece that keeps a key from the agent, and its setup guides are for agents in Modal, Daytona, E2B, Kubernetes and Docker.

Docker Sandboxes

Best for: running the agent in a microVM, where it never holds its own API keys.

Docker Sandboxes “run AI coding agents in isolated environments on your machine or on Docker-managed cloud infrastructure,” started with a command such as sbx run claude ~/my-project. Its security model says “The primary trust boundary is the microVM,” and “Outside the workspace and shared skills store, the agent cannot access your host filesystem,” which puts ~/.ssh and ~/.aws out of reach.

Keys go through a proxy on your host that “intercepts outbound requests from the sandbox, looks up the matching credential on the host, and overwrites the auth header before forwarding.” “For proxy-managed credentials, the real value never enters the sandbox — the agent sees only a sentinel like proxy-managed.” sbx secret set-custom covers your own services with “A value keyed to a domain and environment variable,” and a secret can come from “a 1Password secret reference or an AWS Secrets Manager ARN.” It runs ten agents, Claude Code, Codex, Copilot, Cursor and OpenCode among them.

Price: “The sbx CLI and local sandbox compute are free to use, including for commercial work.” Cloud sandboxes are pay-as-you-go.

Watch for: the folder you share is shared whole. sbx run “defaults to the current directory,” and “A direct mount is read-write, so the agent edits your working tree in place,” so a .env in that folder is inside the sandbox with everything else. When SSH_AUTH_SOCK is set, it forwards your SSH agent too: “Sandbox processes can request signatures, but the private keys stay on the host.” Local sandboxes need “macOS Sonoma version 14 or later” on “Apple silicon,” “Windows 11” with “Windows Hypervisor Platform,” or “Ubuntu 24.04 or later” with KVM.

Network secrets in Claude Code’s and Codex’s cloud

Best for: a task that has to call an API, with a key the agent can’t read.

Both labs’ cloud sessions have the same feature under the same name. In Claude Code on the web, “A network secret is an API key or token you store on a cloud environment so Claude can call that API from any session in the environment without seeing the key,” and “the key doesn’t appear in the session’s environment variables or in any file.” In Codex Cloud, “Programs receive a placeholder; the proxy substitutes the real value for allowed destinations.”

The rest of your computer isn’t there at all. Anthropic says “Your repository is cloned into the session’s isolated VM,” and in Codex Cloud “Each new task gets its own isolated workspace from the published environment,” so a .env you never committed stays on your computer.

Price: included with the plan. “Network secrets are available on Pro, Max, Ultra, Team, and Enterprise plans,” and Claude Pro is “$20 if billed monthly.” Codex’s pricing lists “Codex on the web” from Plus, at $20 a month.

Watch for: plain environment variables sit beside network secrets in the same settings, and they aren’t hidden. Claude’s docs say a session reads them “into ordinary environment variables that any command Claude runs can read,” and “Anyone who uses the environment can read the values.” In Codex Cloud, an environment variable is “Passed directly to programs in the environment.” Codex’s substitution “works for HTTPS on port 443,” and on Claude, “A self-hosted environment doesn’t have network secrets.”

Enjoy

Best for: handing an agent a token by name, in any of six agents, with no settings file to write.

Enjoy is a desktop app for Mac, Windows and Linux that runs Claude Code, Codex, Grok Build, Antigravity, Muse Code, and local models through OpenCode, on the plans you already have. A project secret is “a token, API key, or password that the project’s agents use by name, such as GITHUB_TOKEN, without its value being written into your conversation.”

  • Paste, and Enjoy offers to keep it. When you paste a token into a message, “Instead of adding the value to your message, it shows This looks like a GitHub token.” Select Keep as secret, and your message carries the name.
  • The agent asks Enjoy to run the command. “Enjoy runs the command in the project’s folder with the secret set as an environment variable, then gives the agent the output with the value replaced by [GITHUB_TOKEN].”
  • No approval step. “Agents use a project’s secrets whenever they need them. Enjoy doesn’t ask for your approval, in any permission mode.”
  • Values stay on your computer. “They aren’t synced to your other computers or shared with your team,” and with keychain storage on, “project secrets are kept there too.”

Price: one monthly subscription on top of your AI plans, and the first seven days are free, with a card to start. It includes your phone and any browser and one computer; each other computer costs extra each month, and each teammate you invite needs a subscription of their own. See pricing.

Watch for: project secrets are for a token you hand an agent, not for files already in your folder. Enjoy doesn’t stop an agent opening a .env file, and its help says “If an agent reads any file with a key in it, that key goes to the provider too,” so keep Claude Code’s or Codex’s own rules for that. The help is plain about the rest: “A command that uses a secret can still reveal it, for example by printing it reversed or writing it to a file the agent then reads, and it can send a secret wherever it connects.” “Secrets are only in the computer app,” not on your phone or in a browser, and agents “can use a project’s secrets for any request in that project, including one from a team member.” Enjoy isn’t open source, it’s a monthly subscription on top of your AI plans once the free week ends, and scheduled workflows run only while your computer is awake with Enjoy open.

When the built-in rules are enough

If the only secrets in reach are development keys in a .env file, you don’t need to install or buy anything. In Claude Code, the Read deny rules and the sandbox with a credentials list cover the file tools and the scripts. In Codex, a permission profile hides the files from the commands it runs, and shell_environment_policy handles variables. All of it is free and documented by the labs themselves. Anthropic’s security page suggests going further only “For additional isolation,” by running “the whole Claude Code (local mode) process inside the sandbox runtime or a dev container.”

Reach for more when the job changes. A secrets manager earns its place when keys are shared across a team or shouldn’t sit on disk at all. A microVM or a cloud session fits when the agent runs unattended with network access. And a way to hand over a single token by name, which is what Enjoy’s project secrets and the labs’ network secrets do, matters when the agent has to use a production credential you’d never paste into a chat.

How we compared

We read Anthropic’s Claude Code docs on settings, permissions, sandboxing, cloud environments, security and data usage, Claude’s pricing, OpenAI’s Codex docs on permission profiles, configuration, Codex Cloud and pricing, 1Password’s developer docs and pricing, Doppler’s and Infisical’s docs and pricing, Docker’s Sandboxes docs, GitHub’s push protection docs, Apiiro’s report, and Enjoy’s own help on November 9, 2026, and every one is linked below. The configuration examples are the makers’ own, trimmed to the lines that matter, and we didn’t run these setups ourselves. We quote each maker’s own words for its limits and leave out what it hasn’t documented. Codex’s permission profiles are in beta and Claude Code’s sandbox settings change often, so we recheck this guide against its sources at least once a month, and the date at the foot of the page says when we last did.

13.Questions.

Does Claude Code read .env files?

It can, unless you block it. Anthropic’s settings docs show the rule to “stop it reading .env files,” a Read(./.env) entry in the deny list of settings.json. A .claudeignore file “has no effect,” its permissions docs say.

Is a deny rule enough to keep Claude Code out of a .env file?

No. Anthropic says Read deny rules cover Claude’s file tools and the file commands it recognizes, such as cat, but not “a Python or Node script that opens files itself.” For that it points to the sandbox, which is off by default and doesn’t run on native Windows.

How do I stop Codex reading .env files?

With a permission profile in config.toml that denies .env files by pattern under its workspace roots, which OpenAI’s docs say keeps “environment files, generated secrets, or similar credential-bearing files unreadable.” Profiles are in beta, and Codex ignores them when sandbox_mode is set in any loaded config file.

Does 1Password or Doppler hide my keys from the agent?

Only partly. They keep the plaintext out of your project folder and hand it to a command when it runs, so that command still holds the real value. Of its mounted .env file, 1Password says “Once the file is unlocked, every process can read it.” Pair one with a deny rule or a sandbox.

How do I give a coding agent an API key without it seeing the key?

Use a key that’s added outside the agent’s reach. Network secrets in Claude Code’s and Codex’s cloud environments, Docker Sandboxes and Claude Code’s sandbox masking give commands a placeholder and put the real key on matching requests. Enjoy’s project secrets run a command with a secret by name and replace its value in the output.

What should I do if an agent already read a secret?

Replace it with a new one. Claude Code keeps session transcripts “locally in plaintext” for 30 days by default, and what an agent reads goes to the model’s maker with the conversation. 1Password’s docs say moving secrets into it “doesn’t mitigate any past exposure, such as in your Git history or your coding agent memory.”

Enjoy Agentic Industries · Checked against its sources on