Configure permissions changedpermissions
Nearest release: v2.1.246, published 2 hours after this site recorded the change. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
Recorded here
Lines+28added
Lines−16removed
From line
135
where the diff opens
First seen
14 Aug 2026
this site's first read of the page
Recorded edits71to this page, all time
The whole hunk
from line 135, old and new numbered
/
from line 135
135135
136136### Wildcard patterns
137137
138Bash rules support glob patterns with `*`. This configuration allows npm and git commit commands while blocking git push:
138A `*` in a Bash rule matches any text, including spaces, so one rule covers a family of commands. A rule with no `*` matches one exact command.
139139
140<Warning>
141 Put the `*` after the subcommand. In `git log --oneline main`, `git` is the program and `log` is the subcommand, the word that picks what the program does. Claude Code matches everything before the first `*` as written, so those words are what limit the rule: `Bash(git log *)` allows only `git log` commands, and `Bash(git *)` allows every git command.
142</Warning>
143
144Write the command you want Claude to run without asking, and replace the parts that vary with `*`. With this configuration, Claude Code runs npm scripts and git commits without asking and refuses git push:
145
140146```json theme={null}
141147{
142148 "permissions": {
143149 "allow": [
144150 "Bash(npm run *)",
145 "Bash(git commit *)",
146 "Bash(git * main)",
147 "Bash(* --version)",
148 "Bash(* --help *)"
151 "Bash(git commit *)"
149152 ],
150153 "deny": [
151154 "Bash(git push *)"
from line 157
154157}
155158```
156159
160A `*` can go anywhere in the rule: at the start, in the middle, or at the end. Each row shows a rule, commands it matches, and nearby commands it doesn't match:
161
162| You write | Matches | Doesn't match |
163| :--------------------- | :----------------------------------------------------------------------------------- | :------------------------------------- |
164| `Bash(npm run build)` | `npm run build` | `npm run build --watch` |
165| `Bash(npm run *)` | `npm run build`, `npm run test --watch`, `npm run` | `npm install` |
166| `Bash(git log * main)` | `git log --oneline main`, `git log -5 main`, `git log --output=<file> main` | `git log main`, `git push origin main` |
167| `Bash(git * main)` | `git merge main`, `git push origin main`, `git -c core.fsmonitor=<script> diff main` | `git log` |
168| `Bash(* --version)` | `node --version`, `bash -c 'echo hi' --version` | `node -v` |
169| `Bash(ls *)` | `ls -la`, `ls` | `lsof` |
170| `Bash(ls*)` | `ls -la`, `lsof` | |
171| `Bash(* --help *)` | `npm --help x` | `npm --help` |
172
173Three matching rules produce those rows:
174
175* **The `*` stands in for whatever text is in its place.** In `Bash(git * main)`, it stands in for the subcommand, so Claude Code matches every git subcommand and every option before it. That includes `-c`, which makes git run a program you name. In `Bash(* --version)`, the `*` stands in for the program, so any program matches.
176* **A `*` at the end, with a space before it, also matches the bare command.** `Bash(ls *)` matches `ls`, and `Bash(git log *)` matches `git log`. That holds only when the trailing `*` is the rule's only wildcard: `Bash(* --help *)` matches `npm --help x` but not `npm --help`.
177* **The space before a trailing `*` is part of the rule.** `Bash(ls *)` requires a space after `ls`, so `lsof` doesn't match. `Bash(ls*)` has no space, so it matches `lsof` too.
178
157179The `:*` suffix is an equivalent way to write a trailing wildcard, so `Bash(ls:*)` matches the same commands as `Bash(ls *)`.
158180
159181The permission dialog writes the space-separated form when you select "Yes, and don't ask again" for a command prefix. The `:*` form is only recognized at the end of a pattern. In a pattern like `Bash(git:* push)`, the colon is treated as a literal character and won't match git commands.
from line 204
182204
183205### Bash
184206
185Bash permission rules support wildcard matching with `*`. Wildcards can appear at any position in the command, including at the beginning, middle, or end:
186
187* `Bash(npm run build)` matches the exact Bash command `npm run build`
188* `Bash(npm run test *)` matches Bash commands starting with `npm run test`
189* `Bash(npm *)` matches any command starting with `npm `
190* `Bash(* install)` matches any command ending with ` install`
191* `Bash(git * main)` matches commands like `git checkout main` and `git log --oneline main`
192
193A single `*` matches any sequence of characters including spaces, so one wildcard can span multiple arguments. `Bash(git *)` matches `git log --oneline --all`, and `Bash(git * main)` matches `git push origin main` as well as `git merge main`.
194
195When `*` appears at the end with a space before it (like `Bash(ls *)`), it enforces a word boundary, requiring the prefix to be followed by a space or end-of-string. For example, `Bash(ls *)` matches `ls -la` but not `lsof`. In contrast, `Bash(ls*)` without a space matches both `ls -la` and `lsof` because there's no word boundary constraint.
207Bash rules match the whole command text, with `*` standing in for any text. [Wildcard patterns](#wildcard-patterns) shows which commands each rule shape matches and where to put the `*`. The rest of this section covers how Claude Code matches compound commands, wrappers, read-only commands, and redirections.
196208
197209#### Compound commands
198210
No line in this hunk matches that.