The default permission flow asks you to approve every bash command. That’s safe but slow. With pattern matching, you can auto-approve the safe ones.
Granular Bash Permissions
{
"permissions": {
"allow": [
"Bash(git status*)",
"Bash(git log*)",
"Bash(git diff*)",
"Bash(git branch*)",
"Bash(npm test*)",
"Bash(npm run lint*)",
"Bash(npm run build*)",
"Bash(npx tsc*)",
"Bash(ls *)",
"Bash(pwd)",
"Bash(which *)",
"Bash(cat package.json)",
"Bash(gh pr *)",
"Bash(gh issue *)"
],
"deny": [
"Bash(rm *)",
"Bash(git push*)",
"Bash(git reset*)",
"Bash(npm publish*)",
"Bash(curl * | bash*)"
]
}
}
The Pattern
- Auto-approve: anything that only reads state
- Manual approval: anything that modifies state
- Deny outright: anything destructive
Project-Specific Approvals
Add in .claude/settings.json at the project level:
{
"permissions": {
"allow": [
"Bash(docker compose logs*)",
"Bash(kubectl get *)",
"Bash(kubectl describe *)"
]
}
}
Tip
Start restrictive and add patterns as you get annoyed by approvals. If you keep approving the same command, add it to the allow list.