Skip to content

Feature: Parse compound Bash commands and match each component against permissions #16561

@martymcenroe

Description

@martymcenroe

Summary

When a Bash command contains compound operators (&&, |, ;, ||), the permission matcher evaluates the entire string as a single unit. This causes compound commands to require approval even when all individual components would be allowed by existing permission patterns.

Current Behavior

Given this permission configuration:

{
  "allow": [
    "Bash(git:*)",
    "Bash(cd:*)",
    "Bash(poetry:*)"
  ]
}

The command cd /path && git status:

  • Is evaluated as a single string
  • Does not match Bash(git:*) (starts with cd)
  • Does not match Bash(cd:*) (contains more than just cd)
  • Result: Triggers approval dialog

Expected Behavior

The command cd /path && git status:

  • Is parsed into components: cd /path, git status
  • Each component is matched against permission patterns:
    • cd /path → matches Bash(cd:*)
    • git status → matches Bash(git:*)
  • All components allowed → no approval dialog

Proposed Solution

Modify the permission matching logic for Bash commands to:

  1. Detect compound commands - Check for &&, ||, |, ; outside of quoted strings
  2. Parse into components - Split on these operators
  3. Evaluate each component - Match each against allow/deny patterns
  4. Aggregate results:
    • If ANY component matches a deny pattern → deny
    • If ALL components match allow patterns → allow
    • Otherwise → require approval

Implementation Considerations

Parsing Edge Cases

Case Handling
echo "foo && bar" Don't split inside quotes
$(cd /tmp && ls) Parse subshell contents
cmd1 || cmd2 Handle || (OR) same as &&
cmd1 | cmd2 Pipe - both sides must be allowed
Nested: (a && b) | c Recursive parsing

Security Considerations

  • Deny patterns should be checked first and take precedence
  • A compound command with ANY denied component should be denied
  • Empty components (e.g., && &&) should be rejected

Workaround

Currently, users must either:

  1. Avoid compound commands entirely (use separate Bash calls)
  2. Add broad permission patterns that may be overly permissive

Environment

  • Claude Code CLI
  • Affects all platforms

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions