Settings Precedence
Four settings files contribute to the final permission set. Higher-priority files win when keys conflict. tool-gates respects every explicit rule before applying its own gate decisions.
File priority
Where rules live.
Top of the list wins. The same precedence applies on macOS and Linux.
| Priority | Location | Use case |
|---|---|---|
| 1 highest |
/etc/claude-code/managed-settings.json (Linux)/Library/Application Support/ClaudeCode/managed-settings.json (macOS)C:\Program Files\ClaudeCode\managed-settings.json (Windows)
|
Enterprise managed. Locked by IT; overrides everything below. |
| 2 | .claude/settings.local.json |
Local project overrides. Per-developer, not committed. |
| 3 | .claude/settings.json |
Shared project rules. Committed; team baseline. |
| 4 lowest | ~/.claude/settings.json |
Personal defaults across every project on this machine. |
Interaction
How tool-gates respects your rules.
Your explicit settings.json rules override tool-gates' built-in decision in every case but one: a dangerous call stays blocked even if a rule allows it.
| settings.json | tool-gates | Result |
|---|---|---|
deny rule |
any | Deny explicit deny respected. |
ask rule |
any | Ask two-button prompt (Yes / No). |
allow rule |
dangerous | Deny tool-gates still blocks the dangerous floor. |
allow or none |
safe | Allow |
| none | unknown | Defer in default / acceptEdits; Ask in auto; Block in plan unless the gate proves the command is read-only. |
When a permissions.deny rule matches, the decision reason names the exact Bash(...) pattern. This lets the agent identify the configured boundary that rejected the command instead of receiving a generic settings denial.
Pattern formats
How rules match commands.
| Pattern | Type | Matches |
|---|---|---|
Bash(git:*) | Word-boundary prefix | The : splits on spaces. Matches git, git status, git push; NOT github. |
Bash(cat /dev/zero*) | Glob prefix | Matches anything that starts with the literal prefix. |
Bash(pwd) | Exact | Only the exact command, no trailing args. |
Bash(uv run $HOME/scripts/*) | $HOME expansion | tool-gates expands $HOME in a pattern to the home directory before matching. (Claude Code itself natively expands the ~/ form.) |
Specificity resolution
When ask and allow both match.
Specificity is the length of the non-wildcard prefix. The more specific pattern wins; exact matches are highest. Ties go to ask, the safer default. Bash(mytool --verbose:*) (length 16) beats Bash(mytool:*) (length 6), so a narrow allow can override a broad ask. Deny rules are checked first and use simple matching with no specificity comparison.
When a permissions.ask rule in settings.json matches, Claude Code's resolver shows a two-button prompt instead of three (the "don't ask again for X" button is suppressed). tool-gates rules ask-audit categorises each rule by what tool-gates would do without it (gate-covered, safety floor, indeterminate) and offers per-rule removal.