Deny rules in settings.json don't block Read tool when absolute paths are used
Bug
Deny rules configured in ~/.claude/settings.json are not enforced when files are read using absolute paths. The Read tool successfully reads files that should be blocked.
Settings
{
"permissions": {
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(**/.env*)"
]
}
}
These rules were configured in ~/.claude/settings.json (global settings) before any Claude Code session was started.
Expected behavior
A Read call targeting any .env file — regardless of whether the path is relative or absolute — should be denied.
Actual behavior
Claude Code read /home/<user>/dev/project/server/.env without any permission prompt or denial, despite all three deny rules being present. The file contents were returned and included in the conversation context.
Likely cause
The deny rule patterns use relative/glob syntax (./.env, **/.env*), but the Read tool resolves file paths to absolute paths before matching. The permission system appears to not normalize paths before checking against deny rules, so an absolute path like /home/user/project/.env doesn't match the glob pattern **/.env*.
Environment
- Claude Code (VS Code extension)
- Linux
- Global settings file:
~/.claude/settings.json
Impact
This is a security concern — deny rules exist specifically to prevent sensitive files (like .env files containing secrets) from being read. If absolute paths bypass these rules, the deny list is ineffective.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗