v2.1.121 VSCode native extension: permissions.deny rules not enforced
Summary
permissions.deny rules in ~/.claude/settings.json are not enforced when running Claude Code v2.1.121 in the VSCode native extension. Reads on paths matching active deny entries return file content instead of permission errors. The same settings.json should match per the documented behavior ("Rules are evaluated in order: deny -> ask -> allow. The first matching rule wins, so deny rules always take precedence." — https://code.claude.com/docs/en/permissions.md).
Environment
- Claude Code: v2.1.121
- Runtime: VSCode native extension (Mac native app under
/Users/<user>/Library/Application Support/Claude/claude-code/2.1.121/claude.app/) - macOS: Darwin 25.3.0
- Shell: zsh
Reproduction
~/.claude/settings.json:
{
"permissions": {
"allow": [
"Bash(*)",
"Read(*)",
"Write(*)",
"Edit(*)"
],
"deny": [
"Read(/Users/<user>/.codex/auth.json)",
"Read(/Users/<user>/**/.env.op)",
"Read(/Users/<user>/.aws/credentials)",
"Read(/var/mail/<user>)",
"Read(/Users/<user>/**/*.pem)",
"Read(/Users/<user>/**/*.key)"
]
}
}
~/.claude/settings.local.json adds only allow entries, no deny overrides.
In the model conversation, calling the Read tool on either of:
/Users/<user>/.codex/auth.json/Users/<user>/anywhere/under/home/.env.op
returns the actual file content instead of a permission error.
Expected
Per official docs, the deny rules should fire first and reject the call. The Read should fail with a permission error.
Ruled out
- JSON syntax:
python3 -c "json.load(open(...))"parses cleanly. - settings.local.json deny override: it has no
denyarray. - Tilde-vs-absolute path: all entries are absolute.
- Glob pattern:
/Users/<user>/**/.env.opis the documented form. - Managed/policy override at
/Library/Application Support/ClaudeCode/or/etc/claude-code/: neither directory exists. - VSCode user settings: the Code/User/settings.json is unrelated (47 bytes, no Claude entries).
Impact
P0 in environments that rely on permissions.deny to keep secret material out of model context. Currently any path readable to the user shell is reachable to the model regardless of the configured deny list.
Workaround
None at the configuration layer — the configuration is correct per docs. Until fixed, users should treat permissions.deny as not-enforced in the v2.1.121 VSCode native extension and avoid placing trust in it for secret-isolation in this runtime.
Verification after fix
In any future session, attempt Read on a deny-listed path. If it returns a permission error: fixed. If it returns content: still affected.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗