[DOCS] Bash permission docs omit env-var prefix matching semantics
Documentation Type
Incorrect/outdated documentation
Documentation Location
https://code.claude.com/docs/en/permissions
Section/Topic
Permission rule syntax and Tool-specific permission rules → Bash
Current Documentation
The docs currently say:
Bash permission rules support wildcard matching with*. Wildcards can appear at any position in the command, including at the beginning, middle, or end:Bash(npm run build)matches the exact Bash commandnpm run buildBash(npm run test *)matches Bash commands starting withnpm run testBash(npm *)matches any command starting withnpmBash(* install)matches any command ending withinstall*Bash(git * main)matches commands likegit checkout main,git merge main
It also says:
Claude Code is aware of shell operators (like&&) so a prefix match rule likeBash(safe-cmd *)won't give it permission to run the commandsafe-cmd && other-cmd.
And the same page warns:
Bash permission patterns that try to constrain command arguments are fragile. * Redirects: curl -L http://bit.ly/xyz (redirects to github)
What's Wrong or Missing?
Changelog v2.1.97 says Claude Code "Fixed and hardened Bash tool permissions, tightening checks around env-var prefixes and network redirects, and reducing false prompts on common commands."
The permissions page documents wildcard matching, shell-operator handling, and one redirect caveat, but it does not explain the matching semantics for commands that start with environment-variable assignments such as FOO=bar git push.
That omission matters because users rely on these rules to decide which Bash commands should be covered by a given allow or deny pattern. Today the page gives examples only for bare commands, so it is unclear whether leading env-var prefixes are ignored, normalized, or treated as part of the literal command string.
The redirect warning is also underspecified after the v2.1.97 hardening work. The page still lists redirects only as a generic fragility example, without clarifying what is now enforced versus what still requires WebFetch(domain:...), deny rules for network tools, or a PreToolUse hook.
Suggested Improvement
Add a short subsection under Bash permission rules that documents command-normalization behavior before rule matching.
Suggested coverage:
- State whether leading environment-variable assignments are ignored for matching, with examples such as
FOO=bar git push origin mainandAWS_PROFILE=prod aws s3 ls. - Clarify how Bash permission rules treat leading env-var prefixes before matching.
- Update the redirect caveat to distinguish current behavior after v2.1.97 from remaining unsupported or unsafe cases.
- Add one example showing the recommended safe pattern for network access control: deny Bash network tools, use
WebFetch(domain:...)for allowed domains, and fall back to hooks for stricter validation.
Impact
Medium - Makes feature difficult to understand
Additional Context
Affected Pages:
| Page | Context |
|------|---------|
| https://code.claude.com/docs/en/permissions | Primary Bash permission rule syntax and caveats |
| https://code.claude.com/docs/en/troubleshooting | "Repeated permission prompts" sends users to the permissions page without explaining these matching edge cases |
Total scope: 2 pages affected
Source: Changelog v2.1.97
Changelog entry: Fixed and hardened Bash tool permissions, tightening checks around env-var prefixes and network redirects, and reducing false prompts on common commands
Showing cached comments. Read the full discussion on GitHub ↗
5 Comments
Just checked the current docs again. This issue is not fully resolved yet.
Still relevant as of 2026-05-28. I checked the current docs and this documentation gap still appears unresolved.
Verified against the latest docs; this still appears unresolved.
I have permissions allowing claude to run the ls command.
ls✅ (allowed)ENV foo=bar ls❌ (requests permission)So environment variables break the permissions. Amazing.
The permissions page now documents this. Under https://code.claude.com/docs/en/permissions#process-wrappers: Claude Code strips a leading assignment of certain known-safe environment variables, so
Bash(npm test *)matchesNODE_ENV=test npm test; an allow rule won't match past an assignment of any other variable; and a deny or ask rule matches past any leading assignment, soBash(rm *)in deny still matchesFOO=bar rm -rf tmp/. The same section covers the wrapper commands (timeout,nice,xargs, etc.) that are stripped before matching.Closing as the doc gap is covered.
🤖 Generated with Claude Code