permissions.deny Read rules cannot fence the project auto-memory directory (~/.claude/projects/<cwd-slug>/memory/*)

Status Fixed / completed
Reported on v2.1.233
Maintainer reply ✓ Yes — bcherny
Activity 3 comments · opened Aug 15, 2026 · closed Aug 17, 2026
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

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:

  1. A glob deny: "deny": ["Read(~/.claude/**)"] — other ~/.claude paths are denied as expected; the current project's projects/<cwd-slug>/memory/* files are still readable.
  2. An exact literal-path deny on one specific memory file — that exact file is still readable.
  3. CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 in 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)

View original on GitHub ↗

3 Comments

bcherny collaborator · 1 month ago

I tried to reproduce this on 2.1.233 (Linux, headless claude -p --permission-mode dontAsk), following your steps exactly: a marker MEMORY.md under ~/.claude/projects/<slug>/memory/ and a control file under ~/.claude/other/.

With "deny": ["Read(~/.claude/**)"], both reads were blocked with File 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 form Read(//home/you/.claude/.../MEMORY.md) blocks correctly. See rule syntax.

Another likely explanation: if CLAUDE_CODE_CONFIG / CLAUDE_CONFIG_DIR is set, memory lives under $CLAUDE_CONFIG_DIR/projects/<slug>/memory/, which Read(~/.claude/**) correctly doesn't cover — you'd need a deny on that path instead.

Could you share: claude --version output, whether CLAUDE_CONFIG_DIR is 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 no CLAUDE_CONFIG_DIR, we'll dig further.

🤖 Generated with Claude Code

github-actions[bot] · 1 month ago

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.

github-actions[bot] · 8 days ago

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.