Feature Request: Add 'prompt' list to permission rules for conditional confirmation
Title: Feature Request: Add 'prompt' list to permission rules for conditional confirmation
Labels: feature-request, enhancement, permissions, security
Body
Is your feature request related to a problem? Please describe.
The current tool permission system in Claude Code is powerful but operates on a binary allow / deny logic. As documented in /docs/claude-code/iam and /docs/claude-code/settings, a tool pattern is either allowed to run without user interaction (if it matches a rule in the allow list) or it requires a confirmation prompt.
This creates a dilemma for commands that have both safe and dangerous variants. A great example is git:
- A user might want to allow common, low-risk commands like
git pushorgit committo run without prompts to reduce friction. They could addBash(git push:*)to theirallowlist. - However, a command like
git push --forceis significantly more dangerous and should always be reviewed by the user before execution.
Under the current system, allowing Bash(git push:*) also implicitly allows Bash(git push --force:*), creating a potential safety issue. The only alternative is to not allow Bash(git push:*) at all, forcing the user to manually approve every single push. This leads to "permission fatigue" and a worse user experience.
Describe the solution you'd like
I propose enhancing the permission system by introducing a new prompt list within the permissions object in settings.json.
This list would contain tool patterns that should always trigger a confirmation prompt, even if a broader pattern is present in the allow list. This adds a crucial layer of granular control.
The new order of precedence for permission checks would be:
deny: If a tool call matches a rule in thedenylist, it is blocked. This remains the highest priority.prompt: If a tool call matches a rule in thepromptlist, the user is prompted for confirmation. This rule is evaluated before theallowlist.allow: If a tool call matches a rule in theallowlist (and not apromptordenyrule), it executes without a prompt.- Default: If no specific rule is matched, the default behavior (prompt the user for confirmation) is triggered.
Example settings.json Configuration
{
"permissions": {
"allow": [
"Bash(git push:*)",
"Bash(git pull:*)"
],
"prompt": [
"Bash(git push --force:*)",
"Bash(git rebase:*)"
],
"deny": [
"Bash(rm -rf /*)"
]
}
}
Use Case Example
With the configuration above, the behavior would be as follows:
| Command Executed by Claude | Matched Rule(s) | Result |
| ------------------------------------------ | ---------------------------------------------- | ---------------------- |
| git push origin main | allow: Bash(git push:*) | Allowed (no prompt) |
| git push --force origin main | prompt: Bash(git push --force:*) | Prompted for confirmation |
| git rebase -i HEAD~3 | prompt: Bash(git rebase:*) | Prompted for confirmation |
| git commit -m "..." | (No match) | Prompted (default behavior) |
| rm -rf / | deny: Bash(rm -rf /*) | Blocked immediately |
This model provides the perfect balance: it reduces friction for common, safe operations while ensuring that high-risk variants are always scrutinized by the user.
Describe alternatives you've considered
- Using
PreToolUseHooks: It is technically possible to implement this logic using a [PreToolUse hook](/en/docs/claude-code/hooks). A script could inspecttool_input.commandfor dangerous patterns and return a JSON payload ("permissionDecision": "ask") to force a prompt.
- Downside: This is significantly more complex for the end-user. It requires writing and maintaining a script, whereas the proposed feature is a simple, declarative entry in a JSON file. It also moves security policy from a centralized, readable config into imperative code, making it harder to audit.
- Not Allowing Broad Commands: The user could simply avoid adding
Bash(git push:*)to theallowlist and approve every push manually.
- Downside: This increases friction for very common and safe operations, leading to "permission fatigue" and undermining one of the key benefits of an agentic workflow.
Additional context
This feature provides a more sophisticated and practical security model that aligns with real-world developer workflows. It enables teams and individuals to establish powerful "guardrails" that encourage safe practices without adding friction to routine, low-risk operations. By resolving the tension between security and usability, this enhancement would improve both the safety and the overall user experience of Claude Code.
Additional usage examples:
1. File System Operations (rm)
Scenario: You want to allow Claude to clean up specific log files or temporary artifacts without confirmation, but you want to be prompted before any recursive deletion, which could be catastrophic.
Configuration (settings.json):
{
"permissions": {
"allow": [
"Bash(rm /tmp/claude-logs/*.log)"
],
"prompt": [
"Bash(rm -r*)"
],
"deny": [
"Bash(rm -rf /*)"
]
}
}
Use Case Breakdown:
| Command Executed by Claude | Matched Rule(s) | Result |
| ----------------------------------- | --------------------------- | ---------------------- |
| rm /tmp/claude-logs/session-1.log | allow | Allowed (no prompt) |
| rm -r ./old-assets | prompt | Prompted for confirmation |
| rm /some/other/file.txt | (No match) | Prompted (default behavior) |
| rm -rf / | deny | Blocked immediately |
Justification: This configuration automates routine cleanup of known, safe file patterns while establishing a critical guardrail against accidental recursive deletion of entire directories.
2. Cloud Infrastructure Management (aws s3)
Scenario: You frequently use Claude to list S3 buckets and upload files, which are non-destructive operations. However, any action that deletes objects or buckets must be explicitly approved.
Configuration (settings.json):
{
"permissions": {
"allow": [
"Bash(aws s3 ls*)",
"Bash(aws s3 cp * s3://*)"
],
"prompt": [
"Bash(aws s3 rm*)",
"Bash(aws s3 sync * --delete*)",
"Bash(aws s3 rb*)"
],
"deny": [
"Bash(aws iam delete-user*)"
]
}
}
Use Case Breakdown:
| Command Executed by Claude | Matched Rule(s) | Result |
| --------------------------------------------- | ------------------------------- | ---------------------- |
| aws s3 ls | allow | Allowed (no prompt) |
| aws s3 cp report.pdf s3://my-bucket/ | allow | Allowed (no prompt) |
| aws s3 rm s3://my-bucket/old-report.pdf | prompt | Prompted for confirmation |
| aws s3 sync ./dist s3://my-bucket --delete | prompt | Prompted for confirmation |
| aws s3 rb s3://legacy-bucket --force | prompt | Prompted for confirmation |
Justification: This allows Claude to act as a helpful assistant for routine cloud storage tasks while ensuring a human is in the loop for any potentially destructive operations like deleting files, buckets, or running a sync with the --delete flag.
3. Package Management (npm)
Scenario: For a Node.js project, you want to automate installing dependencies and running tests. However, publishing a new version to the registry or uninstalling a package are sensitive actions that require review.
Configuration (settings.json):
{
"permissions": {
"allow": [
"Bash(npm install)",
"Bash(npm ci)",
"Bash(npm test)"
],
"prompt": [
"Bash(npm uninstall*)",
"Bash(npm publish*)",
"Bash(npm * -g*)"
],
"deny": [
"Bash(npm set registry*)"
]
}
}
Use Case Breakdown:
| Command Executed by Claude | Matched Rule(s) | Result |
| ------------------------------- | --------------- | ---------------------- |
| npm install | allow | Allowed (no prompt) |
| npm test | allow | Allowed (no prompt) |
| npm uninstall lodash | prompt | Prompted for confirmation |
| npm publish | prompt | Prompted for confirmation |
| npm install -g typescript | prompt | Prompted for confirmation |
Justification: This configuration streamlines the common development loop (install -> test) while adding crucial checks for actions that modify the project's dependencies, affect the global environment, or release code to the public.
4. Database & Container Management (kubectl & psql)
Scenario: You use Claude to debug applications in Kubernetes. You want it to be able to view logs and pod details, and even run read-only SQL queries. However, deleting cluster resources or modifying database records must require confirmation.
Configuration (settings.json):
{
"permissions": {
"allow": [
"Bash(kubectl logs*)",
"Bash(kubectl describe*)",
"Bash(psql* -c \"SELECT*)"
],
"prompt": [
"Bash(kubectl delete*)",
"Bash(kubectl apply*)",
"Bash(psql* -c \"DROP*)",
"Bash(psql* -c \"DELETE*)",
"Bash(psql* -c \"UPDATE*)",
"Bash(psql* -c \"TRUNCATE*)"
],
"deny": [
"Bash(kubectl delete namespace kube-system)"
]
}
}
Use Case Breakdown:
| Command Executed by Claude | Matched Rule(s) | Result |
| ---------------------------------------------------- | --------------- | ---------------------- |
| kubectl logs my-app-pod-123 | allow | Allowed (no prompt) |
| psql -U user -d db -c "SELECT * FROM products;" | allow | Allowed (no prompt) |
| kubectl delete pod my-app-pod-123 | prompt | Prompted for confirmation |
| psql -U user -d db -c "UPDATE users SET active=0;" | prompt | Prompted for confirmation |
Justification: This empowers the agent to be a powerful diagnostic tool, allowing it to freely gather information from a running system. At the same time, it establishes strong protections to prevent it from accidentally altering the state of the cluster or the data in the database.
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗