[BUG] global/local settings.json allow permissions are not respected by Claude Code

Open 💬 20 comments Opened Dec 7, 2025 by AbdelrahmanHafez

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?

Piped bash commands prompt for permission even when ALL individual components are already allowed in settings.json.

I have many bash commands allowed in my global settings.json:

"Bash(ls:*)",
"Bash(awk:*)",
"Bash(wc:*)",
"Bash(echo:*)"

Each command works fine individually:

  • ls /some/path - works without prompting
  • awk --version - works without prompting

But piped commands prompt for permission even when ALL components are allowed:

  • ls /some/path | awk '{print $1}' - prompts for permission
  • echo "test" | wc -l - prompts for permission

This is because the permission system uses prefix matching on the entire command string. Bash(awk:*) only matches commands that START with awk, not commands where awk appears after a pipe.

What Should Happen?

If I run cmd1 | cmd2 | cmd3 and each of cmd1, cmd2, cmd3 individually matches an allowed pattern, the full piped command should be allowed without prompting. Same for &&, ||, and ;.

Steps to Reproduce

  1. Add bash command permissions to global or local settings.json:

``json
{
"permissions": {
"allow": [
"Bash(ls:*)",
"Bash(awk:*)",
"Bash(wc:*)",
"Bash(echo:*)"
]
}
}
``

  1. Ask Claude Code to run a simple allowed command like ls /tmp - it runs without prompting
  2. Ask Claude Code to run a piped command like ls /tmp | wc -l - it prompts for permission despite both ls and wc being individually allowed

Claude Model

Not sure / Multiple models

Is this a regression?

No, this never worked

Last Working Version

_No response_

Claude Code Version

2.0.61 (Claude Code)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

iTerm2

Additional Information

I created a PreToolUse hook for a workaround, you can run npx claude-code-plus to get this behavior installed on your machine: claude-code-plus.

View original on GitHub ↗

20 Comments

github-actions[bot] · 7 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/11775
  2. https://github.com/anthropics/claude-code/issues/1271
  3. https://github.com/anthropics/claude-code/issues/12919

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

lucasmccomb · 6 months ago

Would love a fix for this :)

kristofenyi · 5 months ago

Looking forward for a fix on this.

hrism · 5 months ago

At least make sure Claude Code himself is aware of this bug.

sdelicata · 5 months ago

Any news on this? This bug is very annoying...

AbdelrahmanHafez · 5 months ago

For anyone still having issues with this, Anthropic shipped _some_ improvements in 2.1.0, but it still doesn't work well enough.

I encourage you to try claude-code-plus, I solved this in a more sophisticated way than their conservative approach while still being safe, and soon will ship an update that allows you to do regular expressions for permissions.

The way it works is that it parses the commands, regardless of how complex they are and breaks them down into their individual parts and compares each individual part to the permissions. Read some of the tests to get an idea on how we handle complex scenarios.

jason-engage · 5 months ago

This also is not respected:

"allow": [
"Write(./**)",
],
"ask": [
"Write"
],

will always ask for permission even when creating new files in project dirs

sdelicata · 5 months ago

To me, the problem is solved with the new 2.1.19 Claude Code release.

boredbob · 4 months ago

still happening for me, I think it depends on pipe order -- find | grep, grep | head etc

really annoying, especially for /code-review:code-review plugin

Only fix really is to exit, run with --resume --dangerously-skip-permissions temporarily

rythazhur · 4 months ago

Still broken.

TianyuDu · 4 months ago

Still an issue ; (

nbapps · 4 months ago

Same with explore agent, This problem is making me crazy, because I have to authorize every order (and I can't authorize them all...) 30 times in a row each time Explore is called.

damusix · 4 months ago

@nbapps @TianyuDu try https://github.com/damusix/ai-tools, in particular: auto-approve-compound-bash

It should reduce it quite a bit. There are 2 permission guards: The one you allow / deny, and the one that you cannot override (CC detects cd && git combinations that are not overridable, for example)

yurukusa · 3 months ago

Hooks in ~/.claude/settings.json work globally regardless of project-level settings — they're a reliable alternative when permissions don't apply at the project level.

// ~/.claude/settings.json (user-level, always applies)
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [{"type":"command","command":"~/.claude/hooks/destructive-guard.sh"}]
    }]
  }
}

Unlike permission rules, hooks fire at every level (user and project) and aren't overridden by project settings. If your allow/deny rules are being ignored at the project level, moving the logic into hooks is the most reliable workaround.
Quick setup: npx cc-safe-setup installs 8 hooks in user-level settings.

66RED99 · 3 months ago

still facing this issue

vittorioromeo · 3 months ago

@bcherny Can you please prioritize this? It's open since 2025 and makes Claude Code a complete pain to use. I have to constantly manually approve basic commands such as find or cmake.

ChristianTrummer99 · 3 months ago

still an issue. Super weird because this:

  "permissions": {
    "allow": [
      "Bash(*)"
    ]
  },

works as expected (no prompt for any bash command, eg. touch ~/file.txt)
but this

  "permissions": {
    "allow": [
      "Bash(touch *)"
    ]
  },

still requires my approval when running touch ~/file.txt for instance.

AbdelrahmanHafez · 3 months ago

@ChristianTrummer99 try Bash(touch:*), you have a missing colon in the second example.

ChristianTrummer99 · 3 months ago
@ChristianTrummer99 try Bash(touch:*), you have a missing colon in the second example.

I've tried this too. Doesn't make a difference.

here's my actual settings file:

{
  "permissions": {
    "allow": [
      "Edit",
      "Write",
      "MultiEdit",
      "Bash(touch:*)"
    ]
  },
  "sandbox": {
    "enabled": true,
    "autoAllowBashIfSandboxed": true,
    "allowUnsandboxedCommands": true
  }
}

I suspect the harness's handling of sandboxing is what causes this issue.

AbdelrahmanHafez · 3 months ago

Try out claude-code-plus npx claude-code-plus, I've been using it for ~4 months and it solved all my issues. Admittedly, I don't use any of the sandboxing features, but I don't think it should be relevant to this issue.