permissions.deny Read rules cannot fence the project auto-memory directory (~/.claude/projects/<cwd-slug>/memory/*)
Summary
On Claude Code 2.1.233 (Linux, headless claude -p usage), permissions.deny Read rules do not block reads of the current project's auto-memory directory (~/.claude/projects/<cwd-slug>/memory/*). The directory appears to have a structural exemption keyed off the cwd's project slug, independent of the deny rules and of the auto-memory feature flag.
Reproduction (verified three independent ways, 2026-08-14, v2.1.233)
Running a headless session with --permission-mode dontAsk and a settings payload containing each of the following, the model could still Read files under the current project's memory dir in full:
- A glob deny:
"deny": ["Read(~/.claude/**)"]— other~/.claudepaths are denied as expected; the current project'sprojects/<cwd-slug>/memory/*files are still readable. - An exact literal-path deny on one specific memory file — that exact file is still readable.
CLAUDE_CODE_DISABLE_AUTO_MEMORY=1in the environment — memory is not injected automatically, but explicit Read of the memory files still succeeds.
A control shows deny rules working normally for non-memory paths in the same session (tool_result errors: "File is in a directory that is denied by your permission settings").
Why it matters
Deny-rule-based read-only containment (e.g. a sandboxed evaluation/probe agent given --tools Read,Grep,Glob plus a deny list) cannot fence memory content for any cwd whose slug has an existing memory directory. Project memory dirs commonly contain exactly the kind of environment/infrastructure notes a contained agent shouldn't see. The only workaround we found is running contained sessions from a freshly-created path whose slug has no memory directory — which we now enforce mechanically on our side.
Expected
Either permissions.deny Read rules apply to the project memory directory like any other path, or the exemption is documented so containment designs don't assume deny coverage there.
Related
- #73893 (subagents accessing paths outside approved permission boundaries — same "boundary has an exemption" shape)
- #30519 (permissions matching meta-issue)
3 Comments
I tried to reproduce this on 2.1.233 (Linux, headless
claude -p --permission-mode dontAsk), following your steps exactly: a markerMEMORY.mdunder~/.claude/projects/<slug>/memory/and a control file under~/.claude/other/.With
"deny": ["Read(~/.claude/**)"], both reads were blocked withFile is in a directory that is denied by your permission settings.A control run with no deny rules confirmed auto-memory was active in my session (the memory file was auto-readable there), so the deny won over a live memory path, which is the intended precedence.One thing I did reproduce: an exact-path deny written with a single leading slash (
Read(/home/you/.claude/.../MEMORY.md)) does not block, because a single/anchors the rule relative to its source, not the filesystem root. The absolute formRead(//home/you/.claude/.../MEMORY.md)blocks correctly. See rule syntax.Another likely explanation: if
CLAUDE_CODE_CONFIG/CLAUDE_CONFIG_DIRis set, memory lives under$CLAUDE_CONFIG_DIR/projects/<slug>/memory/, whichRead(~/.claude/**)correctly doesn't cover — you'd need a deny on that path instead.Could you share:
claude --versionoutput, whetherCLAUDE_CONFIG_DIRis set, the exact deny rule strings you used, and the exact tool_result text from the memory read? If deny still fails for you with//-anchored rules and noCLAUDE_CONFIG_DIR, we'll dig further.🤖 Generated with Claude Code
We weren't able to reproduce this. Could you provide steps to trigger the issue — what you ran, what happened, and what you expected? This issue will be closed automatically if there's no activity within 7 days.
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.