[BUG] Security: permissions.deny rules not working

Status Open
Reported on v2.1.140
Maintainer reply ✓ Yes — ant-kurt
Activity 6 comments · opened May 21, 2026
💡 Likely answer: A maintainer (ant-kurt, collaborator) responded on this thread — see the highlighted reply below.

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Claude can read an example.key file (or any other key file) inside the project directory even if the ~/.claude/settings.json clearly forbids that:

{
  "theme": "auto",
  "model": "opus",
  "sandbox": {
    "enabled": true,
    "failIfUnavailable": true,
    "allowUnsandboxedCommands": false,
    "autoAllowBashIfSandboxed": false,
    "filesystem": {
      "denyRead": ["//**"],
      "allowRead": [
        "~/Sites/example"
      ]
    }
  },
  "permissions": {
    "deny": [
      "Read(/**/*.key)"
    ]
  }
}

What Should Happen?

Claude should not be able to read those sensitive files, and should respect permissions.

Error Messages/Logs

Steps to Reproduce

  1. Create that ~/.claude/settings.json file with the content above
  2. Create an example.key file in the project directory
  3. Ask Claude to read that file

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.140 (Claude Code)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗

5 Comments

github-actions[bot] · 3 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/61208
  2. https://github.com/anthropics/claude-code/issues/51211
  3. https://github.com/anthropics/claude-code/issues/47686

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

collimarco · 3 months ago

Seems to work with "Read(//**/*.key)" instead of "Read(/**/*.key)"...

In any case this looks like a bug or something not documented properly.

moizxsec · 2 months ago

While this is open, here's a drop-in PreToolUse-hook workaround that enforces the deny rules until the native path is fixed:

https://github.com/moizxsec/claude-deny-guard

  • Enforces .env / key / secret deny globs across Read / Edit / Write / MultiEdit / NotebookEdit and Bash (blocks cat .env, curl, etc. by command regex or denied-path reference).
  • Self-protects the hook script, its config, and settings.json from Edit/Write, so Claude can't disable its own guard.
  • Deliberately never emits an allow decision — on a pass it stays silent and exits 0, so it doesn't suppress the native permission prompt for other tools.
  • Emits both the modern permissionDecision: "deny" JSON and exit code 2, for old/new clients.
  • Node-only, zero deps, 17 black-box tests, MIT.

Honest limitation: Bash matching is token-based, so a deliberately obfuscated command can slip past — it raises cost, not a sandbox. But it closes the common .env/secret-read cases today. Rules/PRs welcome.

github-actions[bot] · 1 month ago

Closing for now — inactive for too long. Please open a new issue if this is still relevant.

ant-kurt collaborator · 17 days ago

Reopening — this is a real bug and not a duplicate of #61208 (that one is about confining reads to a region; this one is about a more specific deny inside an allowed region).

Two things are going on in the report:

  1. Read(/**/*.key) with a single leading slash is resolved relative to the settings file's directory; Read(//**/*.key) (double slash) is filesystem-root-anchored, which is what you found. That part is working as documented, though it's clearly easy to trip over.
  2. Once spelled //**/*.key, the built-in Read tool is blocked, but on macOS a sandboxed Bash command (cat example.key) can still read the file when it's inside a sandbox.filesystem.allowRead region: the sandbox profile emits the wildcard deny before the allowRead rule and macOS applies the last matching rule. Literal (non-wildcard) denies were already fixed; wildcard denies were not. Linux is not affected.

A fix is in progress in the sandbox runtime; this issue will be updated with the Claude Code version that includes it.

Showing cached comments. Read the full discussion on GitHub ↗