Deny rules with **/directory/* glob pattern fail to match
Bug Description
Permission deny rules using **/directory/* or **/directory/**/* glob patterns fail to match when the pattern includes a directory component after the **/ prefix. File-only patterns like **/.env work correctly.
Reproduction Steps
In ~/.claude/settings.json:
{
"permissions": {
"deny": [
"Write(**/.claude/*)",
"Write(**/.claude/**/*)",
"Read(**/.env)",
"Edit(**/.env)"
]
}
}
- Restart Claude Code session
- Attempt to write
.envin CWD — correctly blocked - Attempt to read
.envin CWD — correctly blocked - Attempt to write
.claude/test.txtin CWD — not blocked (expected: blocked) - Attempt to write
.claude/rules/test.txtin CWD — not blocked (expected: blocked)
Expected Behavior
Write(**/.claude/*) should deny writing to any .claude/ directory at any depth, matching both:
<cwd>/.claude/settings.json~/.claude/hooks/script.py
The **/ prefix should match any path prefix (including empty), consistent with how **/.env matches .env at any depth.
Actual Behavior
**/<filename>patterns (e.g.,**/.env) — work correctly**/<directory>/*patterns (e.g.,**/.claude/*) — fail to match- Explicit path patterns (e.g.,
~/.claude/settings.json) — work correctly
Workaround
Use explicit paths instead of **/ prefix:
{
"permissions": {
"deny": [
"Write(~/.claude/*)",
"Write(~/.claude/**/*)",
"Write(.claude/*)",
"Write(.claude/**/*)"
]
}
}
Environment
- macOS (Darwin 25.2.0)
- Claude Code (latest as of 2026-02-06)
- Sandbox enabled with
autoAllowBashIfSandboxed: true
Impact
This affects users trying to protect .claude/ directories (which contain security-critical settings, hooks, and permissions) using a single portable glob pattern. The workaround requires enumerating each specific path, which is fragile and can miss paths.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗