[BUG]
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 Code Permission System - Multiple Critical UX Issues
Summary
The permission system in Claude Code has several fundamental issues that create constant friction during normal development workflows. Even with comprehensive permissions configured in .claude/settings.json, users are repeatedly prompted for permissions that should already be granted.
Environment
- Claude Code CLI (latest version)
- macOS
- Project with extensive
.claude/settings.jsonconfiguration
Issue 1: Wildcard Pattern Matching Fails for Path-Prefixed Commands
Expected Behavior
A permission like Bash(find:*) should match ANY command starting with find.
Actual Behavior
Claude Code still prompts for permission when the find command includes an absolute path:
find /Users/username/dev/project -type f -name "*.py" | grep -v venv | head -20
Despite having Bash(find:*) in the allow list, I was prompted:
Do you want to proceed?
❯ 1. Yes
2. Yes, allow reading from project/ from this project
3. No
Workaround Required
Had to add redundant, path-specific permission:
"Bash(find /Users/username/dev/project:*)"
This defeats the purpose of wildcard permissions.
---
Issue 2: Conflicting Permission Types (Tool vs Bash)
Expected Behavior
Having "Read" as a top-level tool permission should allow reading any file.
Actual Behavior
Even with "Read" in the permissions allow list, Claude Code prompts for bash commands that read files (like tail, cat, head) - treating them as separate permission domains.
Example
With these permissions configured:
{
"permissions": {
"allow": [
"Read",
"Bash(tail:*)"
]
}
}
Still prompted when running: tail -f /tmp/app.log
Had to add additional specific permissions:
"Bash(tail -f /tmp/:*)",
"Bash(tail /tmp/:*)"
---
Issue 3: Subagents Don't Inherit Parent Permissions
Expected Behavior
When Claude Code spawns subagents (Task tool), they should inherit the permission configuration from the parent session.
Actual Behavior
Subagents prompt for permissions independently, even for actions already approved in the parent context. This results in:
- Repeated permission prompts for the same operations
- Permissions accumulating in
.claude/settings.local.jsoninstead of being recognized fromsettings.json - Users having to manually merge permissions between files
Impact
This creates a terrible experience where:
- A single complex task might prompt for permissions 10+ times
- The
.claude/settings.local.jsonfile grows unbounded - Users have to create custom tooling just to manage permission drift
---
Issue 4: No Project-Scoped Trust
Expected Behavior
When working within a project directory, Claude Code should implicitly trust read operations within that project.
Actual Behavior
Claude Code prompts for permission to read files from the very project it's operating in:
Bash command
find /Users/username/dev/my-project -type f -name "*.py"
Do you want to proceed?
❯ 1. Yes
2. Yes, allow reading from my-project/ from this project
This is the project I'm actively developing in. Of course I want Claude to read from it.
---
Issue 5: settings.local.json Accumulation
Expected Behavior
Session-approved permissions should either:
- Be recognized from the main
settings.json, OR - Have a clear UX for promoting local permissions to permanent ones
Actual Behavior
Permissions accumulate in .claude/settings.local.json (gitignored) over time, creating:
- Inconsistent behavior between sessions
- A growing file of redundant permissions
- No built-in way to review/merge these into
settings.json
Users have to build custom scripts to manage this mess.
---
Proposed Solutions
Short-term Fixes
- Fix wildcard matching -
Bash(command:*)should matchcommand /any/path/here args - Add implicit project trust - Don't prompt for read operations within the current working directory
- Subagent permission inheritance - Subagents should inherit parent permissions
Medium-term Improvements
- Permission promotion UX - When approving a permission, offer "Add to settings.json permanently"
- Permission audit command - Built-in command to review and merge accumulated permissions
- Simplified permission model - Consider collapsing overlapping permission types (Read tool vs Bash read commands)
Long-term Consideration
Consider a trust model more like:
{
"trust": {
"project_directory": true,
"bash_commands": ["git", "npm", "python", "pytest"],
"external_paths": ["/tmp/*"]
}
}
Rather than the current granular-but-broken pattern matching.
---
Current Workaround
I've had to maintain an extensive permissions list with redundant entries to minimize prompts:
{
"permissions": {
"allow": [
"Read",
"Bash(find:*)",
"Bash(find /Users/username/dev/project:*)",
"Bash(tail:*)",
"Bash(tail -f /tmp/:*)",
"Bash(tail /tmp/:*)",
// ... 80+ more entries
]
}
}
This is not sustainable and creates friction that significantly impacts productivity.
---
Conclusion
The permission system is the single biggest pain point in Claude Code. The current implementation:
- Doesn't match permissions as documented
- Creates redundant prompts for already-approved operations
- Fragments permissions across multiple files
- Doesn't trust the project being actively developed
- Requires extensive manual configuration that still doesn't fully work
I love Claude Code's capabilities, but the permission UX needs significant attention.
What Should Happen?
I expect that when I give Claude permission for something that it can remember the permission and apply that without having to continuously interrupt the flow with Redundant requests to be able to read files in the project directory, for example.
Error Messages/Logs
Refer to the above bug report.
Steps to Reproduce
Steps to Reproduce
Reproduce Issue 1: Wildcard Pattern Matching Fails
- Create a new project directory and initialize Claude Code
- Add this to
.claude/settings.json:
``json``
{
"permissions": {
"allow": ["Bash(find:*)"],
"deny": []
}
}
- Start Claude Code:
claude - Ask: "Find all Python files in this project"
- Expected: Command runs without prompting (matches
Bash(find:*)) - Actual: Prompted for permission when Claude runs
find /absolute/path/to/project -name "*.py"
Reproduce Issue 2: Tool Permission vs Bash Permission Conflict
- Add to
.claude/settings.json:
``json``
{
"permissions": {
"allow": ["Read", "Bash(tail:*)"],
"deny": []
}
}
- Start Claude Code:
claude - Ask: "Show me the last 20 lines of /tmp/test.log" (create the file first)
- Expected: Command runs without prompting (has both
ReadandBash(tail:*)) - Actual: Prompted for permission, often asking about the path specifically
Reproduce Issue 3: Subagent Permission Inheritance
- Configure comprehensive permissions in
.claude/settings.json - Start Claude Code:
claude - Ask Claude to perform a complex task that spawns subagents (e.g., "Explore the codebase and summarize the architecture")
- Expected: Subagents inherit parent permissions
- Actual: Subagents prompt for permissions independently, even for already-approved operations
- After session, check
.claude/settings.local.json- it will contain permissions that were already insettings.json
Reproduce Issue 4: No Project-Scoped Trust
- Create a project with
.claude/settings.jsoncontaining"Bash(find:*)" - Start Claude Code from within the project directory
- Ask: "What files are in this project?"
- Expected: Claude reads from current project without prompting
- Actual: Prompted with "Yes, allow reading from project/ from this project" - despite being IN that project
Reproduce Issue 5: settings.local.json Accumulation
- Start with a clean
.claude/settings.jsonwith some permissions - Use Claude Code normally for a few sessions, approving permissions as prompted
- Check
.claude/settings.local.jsonafter several sessions - Actual: File contains dozens of accumulated permissions, many redundant with patterns already in
settings.json - No built-in way to review, dedupe, or merge these into the main settings file
---
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
2.1.15
Claude Code Version
2.1.15 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
iTerm2
Additional Information
_No response_
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗