← All incidents

majorcredential-leakunverifiedcollected

One unreadable Docker folder silently switched off Claude Code's .env read block (unverified report)

A developer blocked `**/.env` with Claude Code's sandbox `denyRead` setting on Linux. In one project it did nothing: nested `.env` files stayed readable to the agent, with no warning or error.

Observed
Severity score
7/10
Blast radius
data
Tags
#claude-code#sandbox#bubblewrap#deny-read#fail-open#docker#secrets

Cause

Per the author, expanding the wildcard walked the project with a recursive directory read that gave up entirely on the first permission error. A database folder created by Docker (mode 0700, owned by another user ID) triggered that error, the failure was swallowed, and the pattern ended up protecting zero paths. Fixed paths such as ./.env were not affected.

Consequence

Secrets in nested .env files were open to the agent's processes while the settings looked correct: a security control that failed open. The author notes that Docker Compose projects with volumes inside the repository routinely create folders like this.

Fix

The upstream sandbox runtime reportedly now keeps walking past permission errors and masks unreadable folders, but the author's Claude Code version (2.1.283) had not picked that up yet. Workarounds: narrow the wildcard (./webapp/**/.env), list fixed paths, move Docker volumes out of the project, and combine several patterns. Test a deny rule by trying to read the file, not by reading the config.

What happened

A Japanese developer set sandbox.filesystem.denyRead: ["**/.env"] in Claude Code’s project settings on Linux, where the sandbox runs on bubblewrap. The idea was simple: whatever the agent does, it should never read an environment file. In one project that worked. In another project, with the same settings, the agent could read nested .env files freely.

The chaos on the ground

There was no error, no warning, nothing in the logs. The only clue was the difference between two projects. The author compared them and found that the broken one contained a folder created by Docker for a PostgreSQL volume, owned by another user ID with permissions the host user could not enter. Creating a single empty folder with chmod 000 was enough to reproduce the problem anywhere.

Root cause

To turn **/.env into concrete paths, the sandbox listed every file under the project with a recursive directory read. That call does not skip folders it cannot open; it stops at the first permission error. The code caught the error and carried on with an empty list, so the rule quietly protected nothing. Rules with fixed paths never went through that step, which is why ./.env stayed blocked.

The fix

According to the author, Anthropic’s open-source sandbox runtime has since replaced the recursive listing with a walk that continues past permission errors and masks the folders it cannot read, but the Claude Code release they tested had not yet taken in that change. Until it does, the author suggests narrowing wildcards to the folders that matter, listing important .env files by fixed path, moving Docker volumes out of the project tree, and layering several patterns.

The wider lesson is about how security settings get checked. A deny rule that fails open looks exactly like one that works. The only reliable test is to have the agent try to read the file it should not be able to read, in every project, after every change.

Sources