Internally-generated Bash commands bypass user's allowlist patterns

Resolved 💬 2 comments Opened Feb 13, 2026 by devinhedge Closed Mar 14, 2026

Problem

Claude Code generates its own Bash commands for internal operations (task monitoring, subagent output checking, etc.) that are complex piped chains. These don't match any reasonable prefix-based allowlist pattern configured in settings.local.json.

Example

When Claude Code monitors a background subagent, it generates commands like:

tail -1 /private/tmp/claude-501/-Users-user-workspace-project/tasks/a01fe67.output 2>/dev/null | python3 -c "import sys,json;
d=json.loads(sys.stdin.read()); print(d.get('type','?'), '-', str(d.get('message',{}).get('content','')[:200]) if
isinstance(d.get('message',{}).get('content',''),str) else d.get('message',{}).get('content',[{}])[0].get('text','')[:200])" 2>/dev/null || echo "Still running"

Even with a comprehensive allowlist (~130 patterns covering Bash(tail:*), Bash(python3:*), etc.), these internally-generated piped commands don't match any single prefix pattern and trigger approval prompts.

Why this is frustrating

  • The user didn't request these commands — Claude Code generated them for its own housekeeping
  • The user can't anticipate the shape of these commands to pre-approve them
  • Adding more allowlist patterns is whack-a-mole — each new internal command chain has a novel structure
  • The approval prompt interrupts autonomous workflows (subagent orchestration) that the user explicitly set up to run hands-off

Suggestion

Two possible improvements (not mutually exclusive):

1. Distinguish internal commands from user-directed commands

If Claude Code generates a command for its own internal operations (checking subagent status, reading task output files, monitoring background processes), it should either:

  • Auto-approve these as system-level operations, or
  • Gate them under a separate permission category (e.g., "allow_internal_commands": true) so users can opt in once rather than per-command

2. Support a deny list alongside the allow list

Let users configure permissions as "allow everything EXCEPT these patterns":

{
  "permissions": {
    "allow": ["Bash(*)"],
    "deny": [
      "Bash(terraform apply:*)",
      "Bash(terraform destroy:*)",
      "Bash(rm -rf:*)",
      "Bash(git push --force:*)"
    ]
  }
}

This would flip the model from "enumerate every safe command" to "block the known-dangerous ones," which is far more practical for power users running complex multi-agent workflows.

Environment

  • Claude Code CLI
  • macOS (Darwin 25.2.0)
  • Using Task tool with multiple concurrent subagents
  • Comprehensive settings.local.json allowlist (~130 patterns)

View original on GitHub ↗

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