Problem
When a command is wrapped in xargs, find -exec, parallel, watch, or similar command wrappers, the permission system only sees the wrapper command, not the inner command being executed.
For example, with this permission config:
"bash": {
"*": "allow",
"gh api* -X DELETE*": "ask"
}
This command bypasses the permission check entirely:
gh api repos/owner/repo/code-scanning/analyses --paginate -q '.[] | .id' | xargs -I{} gh api -X DELETE repos/owner/repo/code-scanning/analyses/{}
The bash tool parses this as two commands via tree-sitter:
gh api repos/... --paginate -q '...' - matches *: allow
xargs -I{} gh api -X DELETE ... - starts with xargs, not gh api, so matches *: allow
The dangerous gh api -X DELETE is never checked because it appears as arguments to xargs, not as a standalone command.
Proposed Solution
The bash tool could recognize common command wrappers and extract their inner commands for permission checking:
xargs [-I...] <command> - extract command after flags
find ... -exec <command> \; or -exec <command> + - extract command between -exec and terminator
parallel <command> - extract command
watch [-n...] <command> - extract command after flags
env [VAR=val...] <command> - extract command after env vars
When a wrapper is detected, both the wrapper invocation AND the inner command should be checked against permission rules.
Workaround
Users can currently work around this by adding a leading * to patterns:
"*gh api* -X DELETE*": "ask"
This matches the pattern anywhere in the command string, but it's non-obvious and easy to miss.
Problem
When a command is wrapped in
xargs,find -exec,parallel,watch, or similar command wrappers, the permission system only sees the wrapper command, not the inner command being executed.For example, with this permission config:
This command bypasses the permission check entirely:
The bash tool parses this as two commands via tree-sitter:
gh api repos/... --paginate -q '...'- matches*: allowxargs -I{} gh api -X DELETE ...- starts withxargs, notgh api, so matches*: allowThe dangerous
gh api -X DELETEis never checked because it appears as arguments toxargs, not as a standalone command.Proposed Solution
The bash tool could recognize common command wrappers and extract their inner commands for permission checking:
xargs [-I...] <command>- extract command after flagsfind ... -exec <command> \;or-exec <command> +- extract command between -exec and terminatorparallel <command>- extract commandwatch [-n...] <command>- extract command after flagsenv [VAR=val...] <command>- extract command after env varsWhen a wrapper is detected, both the wrapper invocation AND the inner command should be checked against permission rules.
Workaround
Users can currently work around this by adding a leading
*to patterns:This matches the pattern anywhere in the command string, but it's non-obvious and easy to miss.