Permissions: command-level matching instead of string prefix matching
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.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗