Feature request: opt-in full bypassPermissions for protected directories (workaround included)
Context
Prior to v2.1.78, bypassPermissions applied universally — all directories, all edits, no prompts. Starting in v2.1.78, writes to .git, .claude, .vscode, and .idea directories prompt for confirmation even with bypassPermissions enabled. The permissions documentation now reflects this as intended behavior: "writes to .git, .claude, .vscode, and .idea directories still prompt for confirmation to prevent accidental corruption of repository state and local configuration."
The guardrail makes sense as a default. However, there's currently no way for users who need full bypass coverage to get it. The documentation recommends bypassPermissions for "isolated environments like containers or VMs where Claude Code cannot cause damage" — but even in those environments, the protected-directory restriction still applies, and there's no configuration to override it.
Use Case
Power users running Claude Code with extensive hook infrastructure, custom .claude/ configurations, and automated workflows hit this constantly. In a session with 175+ hooks, many of which manage files in .claude/ (settings, rules, agent definitions, skills), every edit prompts for confirmation despite bypassPermissions being enabled. The existing carve-outs for .claude/commands, .claude/agents, and .claude/skills help but don't cover the full surface — edits to .claude/settings.json, .claude/settings.local.json, files in .claude/rules/, and .git/ operations all still prompt.
In an isolated local development environment where the user has already opted into bypassPermissions, the remaining prompts add friction without adding safety.
What Exists Today
The Write/Edit permission evaluator calls a file-safety checker that tests paths against .git, .claude, .vscode, and .idea. When the path matches, the evaluator returns a synthetic policySettings rule with ruleBehavior: "ask" before bypassPermissions is consulted. This means:
bypassPermissionscan't override it — the check short-circuits before bypass is evaluated.- PreToolUse hooks can't override it — hooks run before the internal evaluator, and the synthetic rule is generated inside the evaluator.
allowedTools/Edit(*)can't override it — they operate at a different layer than the file-safety checker.- No configuration controls the safety check behavior. The directory list is hardcoded.
The only workaround is binary modification (EDIT: see update below for a simpler workaround), which works but isn't a reasonable long-term solution.
Request
Provide a configuration-level way for users to extend bypassPermissions to cover protected directories. Some possible approaches:
- A separate setting like
bypassProtectedDirectories: true— explicit opt-in, easy to understand, administrators can still block it via managed settings. - Extend the existing carve-out pattern —
.claude/commands,.claude/agents, and.claude/skillsare already exempt. Allow users to add directories to the exempt list. - Make the safety check consult
bypassPermissions— if bypass is enabled, skip the synthetic rule and let the normal permission flow handle it.
The safety check is a good default. The ask isn't to remove it — it's to provide an opt-in for users who've already made the explicit decision to skip permission prompts and understand the implications.
---
Update: PermissionRequest Hook Workaround (simpler)
Thanks to @echthesia for pointing out that a PermissionRequest hook can handle this. Tested and confirmed it works — no binary modification needed.
The policySettings synthetic rule creates a standard permission dialog. PermissionRequest hooks fire after all permission rules have evaluated but before the dialog is shown to the user, and can auto-approve the request. This is much simpler than the binary patch approach described further below.
Setup
Add a PermissionRequest hook to your .claude/settings.local.json (or .claude/settings.json):
{
"hooks": {
"PermissionRequest": [
{
"matcher": "Edit",
"hooks": [
{
"type": "command",
"command": "echo '{\"hookSpecificOutput\":{\"hookEventName\":\"PermissionRequest\",\"decision\":{\"behavior\":\"allow\"}}}'",
"timeout": 5
}
]
},
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": "echo '{\"hookSpecificOutput\":{\"hookEventName\":\"PermissionRequest\",\"decision\":{\"behavior\":\"allow\"}}}'",
"timeout": 5
}
]
}
]
}
}
This auto-approves all Edit and Write permission prompts. If you're already in bypassPermissions mode, the only prompts that still appear are these protected-directory ones, so a blanket auto-approve effectively restores the pre-v2.1.78 behavior.
Targeted version
If you want to auto-approve only for specific directories rather than all permission prompts, use a script that checks the path:
#!/usr/bin/env bash
set -uo pipefail
input="$(cat)"
file_path=$(echo "$input" | python3 -c "import sys,json; print(json.load(sys.stdin).get('tool_input',{}).get('file_path',''))" 2>/dev/null)
if [[ "$file_path" == */.claude/* || "$file_path" == */.git/* || "$file_path" == */.vscode/* || "$file_path" == */.idea/* ]]; then
echo '{"hookSpecificOutput":{"hookEventName":"PermissionRequest","decision":{"behavior":"allow"}}}'
fi
Save it somewhere (e.g., ~/.claude/hooks/auto-approve-protected-dirs.sh), make it executable, and reference it in the hook config instead of the inline echo.
Why this works
The permission lifecycle is:
- Tool call comes in (e.g., Edit to
.claude/settings.json) - PreToolUse hooks run
- Permission evaluation happens — file safety check creates synthetic
policySettingsrule withruleBehavior: "ask" - PermissionRequest hooks fire here — can return
{ behavior: "allow" }to auto-approve - User dialog (never reached if the hook approved it)
The original issue correctly identified that bypassPermissions, PreToolUse hooks, and allowedTools can't override the restriction. PermissionRequest hooks operate at a different point in the lifecycle — they don't try to prevent the rule from being created, they automate the response to it.
Caveats
- The blanket version auto-approves all Edit/Write permission prompts, not just protected-directory ones. In
bypassPermissionsmode this is equivalent, but in other modes it would suppress prompts you might want to see. - Still an unofficial workaround — the underlying request for a configuration-level option stands.
Previous binary solution removed due to simpler fix.
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗