Permissions: command-level matching instead of string prefix matching

Resolved 💬 3 comments Opened Apr 23, 2026 by metawave Closed Apr 27, 2026

Problem

Bash permissions currently use string prefix matching. This leads to several issues:

1. Flags/arguments before the subcommand break matching

"allow": ["Bash(git pull*)"]

This does not match git -C /my-project pull because -C /my-project appears before pull. There's no way to reliably deny git push across all flag combinations (git -C /path push, git --no-pager push, etc.).

2. Pipes break matching

"allow": ["Bash(npm test*)"]

Matches npm test | head, but cat foo | npm test would match Bash(cat*) instead. The allowed command is in the pipeline but not at the string prefix position.

3. No effective deny rules

There's no way to express "allow all git subcommands except push" robustly. A deny rule like Bash(git push*) has the same prefix-matching limitation — git -C /path push would bypass it.

Proposed solution

Parse the Bash command semantically instead of string-matching:

  • Identify the base command and subcommands regardless of flag positions
  • Recognize commands in pipes — match against each segment individually
  • Support deny rules with glob or regex patterns that operate on the parsed command

Example

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

Should deny git push, git -C /path push, git --no-pager push origin main, etc.

Use case

Users who want to work with minimal permission prompts (similar to other AI coding tools) but still maintain guardrails for destructive or externally-visible operations like git push, rm -rf, or docker push.

View original on GitHub ↗

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