Repository navigation
[BUG] permissions from user settings.json is NOT applied at project level #5140
Copy link
Copy link
Open
Labels
area:corearea:permissionsarea:securityarea:toolsbugSomething isn't workingSomething isn't workinghas reproHas detailed reproduction stepsHas detailed reproduction stepsplatform:macosIssue specifically occurs on macOSIssue specifically occurs on macOS
Description
Environment
- Platform (select one):
- Other: Claude Code on macOS with VS Code
- Claude CLI version: 1.0.68 (Claude Code)
- Operating System: macOS Darwin 23.6.0
- Terminal: Terminal App
Bug Description
User-level permissions in ~/.claude/settings.json are not being enforced
during command execution, even though they appear as loaded in the
/permissions command. The same permissions work correctly when placed in
project-level .settings.local.json but fail when moved to user-level
settings.
Steps to Reproduce
- Copy working permissions from a project's .settings.local.json to
user-level ~/.claude/settings.json:
{
"permissions": {
"allow": [
"mix:",
"mcp__serena__",
"mcp__context7__",
"Bash(ls:)",
"Bash(find:)",
"Bash(grep:)",
"Bash(sqlite3:)",
"Bash(mkdir:)",
"Bash(cp:)",
"Bash(mv:)",
"Bash(git add:)",
"Bash(git push:)",
"Bash(git checkout:)",
"Bash(git stash show:)",
"Bash(git stash pop:)",
"Bash(git fetch:)",
"Bash(git stash push:)",
"Bash(git merge:)",
"Bash(git cherry-pick:)",
"Bash(python:)",
"Bash(python3 -m pip install:)",
"Bash(npm install:)",
"Bash(npx playwright test:*)"
]
}
} - Open a project in VS Code with Claude Code
- Run /permissions - it correctly shows all permissions as loaded
- Try to run any allowed command (e.g., mix --version)
- Claude Code still asks for permission despite the command being in the
allow list
Expected Behavior
- I want a way to allow the mcp of serena to execute all its commands without asking for explicit permission each time.
- Commands in the user-level allow list should execute without requiring
approval - User-level permissions should work identically to project-level
permissions - If /permissions shows a command as allowed, it should not require
approval
Actual Behavior
- All commands require manual approval even when listed in user-level
permissions - /permissions command shows the permissions as loaded but they are not
enforced - The exact same permissions work when placed in project
.settings.local.json but not in ~/.claude/settings.json - MCP wildcard permissions (e.g., mcp__serena__*) also don't work at the
user level
Additional Context
- These permissions were originally auto-generated by Claude Code (not
manually written) - I just copied them from .settings.local.json to the user-level settings.json - This significantly impacts workflow as every command requires manual
approval across all projects
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
area:corearea:permissionsarea:securityarea:toolsbugSomething isn't workingSomething isn't workinghas reproHas detailed reproduction stepsHas detailed reproduction stepsplatform:macosIssue specifically occurs on macOSIssue specifically occurs on macOS
Activity
[-][BUG][/-][+][BUG] permissions from user settings.json is NOT applied at project level[/+]github-actions commentedon Aug 5, 2025
Found 3 possible duplicate issues:
If your issue is a duplicate, please close it and 👍 the existing issue instead.
🤖 Generated with Claude Code
wangkanai commentedon Aug 7, 2025
This permissions issue may be related to #5314 - PostToolUse hooks not triggering for Edit operations on .cs files.
The problem in #5314 involves hooks configured in
.claude/settings.jsonnot being executed despite proper syntax and verbose mode being enabled. If permissions from user settings.json are not being applied at the project level as described in this issue, it could explain why PostToolUse hooks fail to execute.Our hook configuration includes:
{ "enableAllProjectMcpServers": true, "verbose": true, "hooks": { "PostToolUse": [...] } }If the settings.json configuration isn't being properly applied at the project level, the hook system might not be receiving the configuration needed to execute hooks after Edit/MultiEdit/Write operations.
Sergiodelahoz commentedon Aug 12, 2025
I'm having the same issue! in MacOS, using claude code, user/.claude/settings.json allow list and deny list commands are completely ignored. It is a bit annoying to deal with this.
tonydehnke commentedon Aug 30, 2025
Same here on MacOS. Would love a real fix.
vhardy commentedon Sep 22, 2025
Same problem on my end. I am trying to run grunt commands from Claude and it keeps asking for permission even though I ask CC to add it to the allow list.
tiagoefreitas commentedon Nov 4, 2025
Same issue, and its extra annoying with plan mode as it does not respect the bypass permissions that I set when launching the cli. The global bypass permissions should be a setting, not a mode. So I tried to workaround by adding permissions and it doesn't use them.
vhardy commentedon Nov 5, 2025
@tiagoefreitas Not sure if this will apply to your situation, but you may want to check
/statuswhen in Claude code to see if there were issues loading the settings file. I discovered that it does not proactively report issues with settings files, so it will silently ignore those with typos for example. But if you run/status, then you'll see a message if there was an issue with one of your settings (it was my .claude/settings.json in my case). Then it took a little trial and error to understand where there was a typo because the message did not give details, but I was able to sort it out. I hope this helps.Sean10 commentedon Nov 5, 2025
According to your advise, I fixed my problem.
7 remaining items
tonydehnke commentedon Dec 29, 2025
This still keeps coming back up. We really could use some attention from the team to fix permissions @bcherny
tiagoefreitas commentedon Dec 31, 2025
between this and claude not reading the user .mcp.json, cc is getting frustrating to use
mrgoonie commentedon Jan 5, 2026
None of these following
settings.jsonworks:With double slashes (at the beginning):
{ "permissions": { "allow": [ "Write(//private/tmp/test-workspaces/permission-test.txt)" ] } }With a single slash (at the beginning):
{ "permissions": { "allow": [ "Write(/private/tmp/test-workspaces/permission-test.txt)" ] } }At
/private/tmp/test-workspaces/.claude/settings.jsonand/private/tmp/test-workspaces/.claude/settings.local.json{ "permissions": { "allow": [ "Write(*)" ] } }At
~/.claude/settings.jsonand~/.claude/settings.local.json:{ "permissions": { "allow": [ "Write(*)" ] } }claudewas being started at/private/tmp/test-workspaces/But it always ask for permissions when writing to
/private/tmp/test-workspaces/permission-test.txt(although it was pre-approved)I don't want to run
claudewith--dangerously-skip-permissionsflag. But runningclaudewithout it is quite frustrating now...Wondering how is it working at Anthropic? @bcherny
mrgoonie commentedon Jan 5, 2026
denyis also not working:/private/tmp/clawk-workspaces/1/.claude/settings.json:{ "permissions": { "deny": [ "Write(permission-test.txt)", "Write(*)" ] } }Start
claudeorclaude --dangerously-skip-permissions:claudestill write outpermission-test.txtjwhartley commentedon Jan 8, 2026
Solution Found: Path Format Issue
After extensive testing, I found that user-level permissions DO work - the issue is the path format.
Root Cause
Single-slash paths like
/Users/james/**are interpreted as relative paths from the settings file location, not absolute paths.The Fix
Use double-slash
//for absolute paths:{ "permissions": { "allow": [ "Read(//Users/james/**)", "Write(//Users/james/github/**)", "Edit(//Users/james/github/**)" ] } }Verification
~/.claude/settings.jsonwith//paths-r)This is documented in #6881 but easy to miss. The single-slash format that Claude Code itself generates when you accept prompts may be contributing to the confusion.
Additional Note
Path-restricted Bash commands like
Bash(rm:/tmp/**)also don't work reliably. Use wildcardsBash(rm:*)with deny rules instead.arnonmoscona commentedon Feb 5, 2026
Got tired of waiting for fixes. Created https://github.com/arnonmoscona/toolguard as an enhanced drop-in replacement to the native permissions system using hooks. As far as I can tell it is syntax-compatible, but it has more features and allows also new matching patterns. The simplest setup is just to setup the hook as documented, but you can go far beyond if you want. I will add a new feature soon to overcome some of the annoying behaviors I find around permissions.
I'd welcome any feedback, comments, PRs. This is new, to treat it carefully. "works on my machine" is not really good enough, but I am one guy with one machine. So there's that...
yurukusa commentedon Mar 21, 2026
Workaround — hooks in user settings.json are enforced regardless of project settings:
While permission rules may not cascade correctly from user to project level, hooks defined in
~/.claude/settings.jsondo apply globally to all projects.{ "hooks": { "PreToolUse": [{ "matcher": "Bash", "hooks": [ { "type": "command", "command": "bash ~/.claude/hooks/destructive-guard.sh" }, { "type": "command", "command": "bash ~/.claude/hooks/branch-guard.sh" } ] }] } }Hooks bypass the permission system entirely — they run before tool execution and exit 2 to hard-block, regardless of what project-level settings say.
Quick install:
npx cc-safe-setup— writes hooks to~/.claude/hooks/and registers them in user-level~/.claude/settings.json. Works across all projects.yurukusa commentedon Mar 29, 2026
User-level permissions in
~/.claude/settings.jsondon't reliably apply at project level — this is a known issue. Hooks are the fix because they always propagate:{ "hooks": { "PreToolUse": [{ "matcher": "Bash", "hooks": [{ "type": "command", "command": "bash ~/.claude/hooks/user-level-permissions.sh" }] }] } }Hooks defined in
~/.claude/settings.jsonfire in every project. Unlike permission patterns, hook execution doesn't have the user/project level scoping bug. This is the reliable way to enforce user-level permissions across all projects.arnonmoscona commentedon Apr 23, 2026
FYI toolguard is now at 0.3.0 - while takeover mode is nominally in alpha state, it's been working perfectly for me for a while. So this issue does not really affect me any more and I have a much more flexible permissions configuration.
https://github.com/arnonmoscona/toolguard](https://github.com/arnonmoscona/toolguard%5D(https://github.com/arnonmoscona/toolguard))
claude: fix bypassPermissions by moving skipDangerousModePermissionPr…
claude: fix bypassPermissions by moving skipDangerousModePermissionPr…
boringstud-io commentedon Jul 22, 2026
On claude.ai/code (cloud sessions incl. scheduled Routines), claude.ai connector tools (Notion MCP) prompt for permission on every call with only “Allow once” — no persistent option. We verified that ALL documented mechanisms are ignored for connector tools: (1) setting every Notion tool to “Always allow” in the connector’s tool-permission settings, (2) permissions.allow: ["mcp__Notion"] in the repo’s .claude/settings.json, (3) a PreToolUse hook returning permissionDecision: "allow" for mcp__Notion__.*. In all three cases a fresh cloud session still prompted for a simple Notion fetch. Scheduled runs hang indefinitely on these prompts.
yozerpp commentedon Oct 10, 2026
I worked to create a design document between 11 pm and 2 am in Friday for claude to analyse sample input/outputs, pages it needs to automate and the architectural design, and make an implementation plan. Only to find out, at the fing morning, that all agents stopped after 10 minutes to ask me to run a db query.
Sacrifice of my sleep to move this newly assigned task forward turned out to be for nothing thanks to Claude. F that.
Edi: if this happens a couple more times until end of the month, I'm out.