Layer persistent allow and deny rules in settings

permissions & tools

// what it does

The permissions object in settings.json holds three arrays: allow runs without prompting, deny blocks outright and can't be overridden, and ask forces a prompt. Rules use Tool(pattern) syntax with glob wildcards, like Bash(npm run test:*) or Read(./src/**). These rules merge across every settings scope rather than replacing each other, and /permissions edits them live in a session.

// shell

$ { "permissions": { "allow": ["Bash(npm run test:*)"], "deny": ["Read(./.env)"] } }
$ /permissions

// gotcha

Because permission arrays accumulate across user, project, local, and managed scopes, a deny rule set anywhere — including a managed policy you can't see — silently blocks a command. Check the effective rules with /permissions when something you allowed still gets refused.

// resources