[BUG]

Resolved 💬 2 comments Opened Jan 22, 2026 by samotage Closed Feb 27, 2026

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.json configuration

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:

  1. Repeated permission prompts for the same operations
  2. Permissions accumulating in .claude/settings.local.json instead of being recognized from settings.json
  3. 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.json file 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:

  1. Inconsistent behavior between sessions
  2. A growing file of redundant permissions
  3. 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

  1. Fix wildcard matching - Bash(command:*) should match command /any/path/here args
  2. Add implicit project trust - Don't prompt for read operations within the current working directory
  3. Subagent permission inheritance - Subagents should inherit parent permissions

Medium-term Improvements

  1. Permission promotion UX - When approving a permission, offer "Add to settings.json permanently"
  2. Permission audit command - Built-in command to review and merge accumulated permissions
  3. 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

  1. Create a new project directory and initialize Claude Code
  2. Add this to .claude/settings.json:

``json
{
"permissions": {
"allow": ["Bash(find:*)"],
"deny": []
}
}
``

  1. Start Claude Code: claude
  2. Ask: "Find all Python files in this project"
  3. Expected: Command runs without prompting (matches Bash(find:*))
  4. Actual: Prompted for permission when Claude runs find /absolute/path/to/project -name "*.py"

Reproduce Issue 2: Tool Permission vs Bash Permission Conflict

  1. Add to .claude/settings.json:

``json
{
"permissions": {
"allow": ["Read", "Bash(tail:*)"],
"deny": []
}
}
``

  1. Start Claude Code: claude
  2. Ask: "Show me the last 20 lines of /tmp/test.log" (create the file first)
  3. Expected: Command runs without prompting (has both Read and Bash(tail:*))
  4. Actual: Prompted for permission, often asking about the path specifically

Reproduce Issue 3: Subagent Permission Inheritance

  1. Configure comprehensive permissions in .claude/settings.json
  2. Start Claude Code: claude
  3. Ask Claude to perform a complex task that spawns subagents (e.g., "Explore the codebase and summarize the architecture")
  4. Expected: Subagents inherit parent permissions
  5. Actual: Subagents prompt for permissions independently, even for already-approved operations
  6. After session, check .claude/settings.local.json - it will contain permissions that were already in settings.json

Reproduce Issue 4: No Project-Scoped Trust

  1. Create a project with .claude/settings.json containing "Bash(find:*)"
  2. Start Claude Code from within the project directory
  3. Ask: "What files are in this project?"
  4. Expected: Claude reads from current project without prompting
  5. Actual: Prompted with "Yes, allow reading from project/ from this project" - despite being IN that project

Reproduce Issue 5: settings.local.json Accumulation

  1. Start with a clean .claude/settings.json with some permissions
  2. Use Claude Code normally for a few sessions, approving permissions as prompted
  3. Check .claude/settings.local.json after several sessions
  4. Actual: File contains dozens of accumulated permissions, many redundant with patterns already in settings.json
  5. 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_

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗