tool-permissions.md

  1# Tool Permissions
  2
  3Configure which [Agent Panel](./agent-panel.md) tools run automatically and which require your approval.
  4For a list of available tools, [see the Tools page](./tools.md).
  5
  6> **Note:** In Zed v0.224.0 and above, tool approval is controlled by `agent.tool_permissions.default`.
  7> In earlier versions, it was controlled by the `agent.always_allow_tool_actions` boolean (default `false`).
  8
  9## Quick Start
 10
 11Use Zed's Settings Editor to [configure tool permissions](zed://settings/agent.tool_permissions), or add rules directly to your settings file:
 12
 13```json [settings]
 14{
 15  "agent": {
 16    "tool_permissions": {
 17      "default": "allow",
 18      "tools": {
 19        "terminal": {
 20          "default": "confirm",
 21          "always_allow": [
 22            { "pattern": "^cargo\\s+(build|test|check)" },
 23            { "pattern": "^npm\\s+(install|test|run)" }
 24          ],
 25          "always_confirm": [{ "pattern": "sudo\\s+/" }]
 26        }
 27      }
 28    }
 29  }
 30}
 31```
 32
 33This example auto-approves `cargo` and `npm` commands in the terminal tool, while requiring manual confirmation on a case-by-case basis for `sudo` commands.
 34Non-terminal commands follow the global `"default": "allow"` setting, but tool-specific defaults and `always_confirm` rules can still prompt.
 35
 36## How It Works
 37
 38The `tool_permissions` setting lets you customize tool permissions by specifying regex patterns that:
 39
 40- **Auto-approve** actions you trust
 41- **Auto-deny** dangerous actions (blocked even when `tool_permissions.default` is set to `"allow"`)
 42- **Always confirm** sensitive actions regardless of other settings
 43
 44## Supported Tools
 45
 46| Tool                     | Input Matched Against        |
 47| ------------------------ | ---------------------------- |
 48| `terminal`               | The shell command string     |
 49| `edit_file`              | The file path                |
 50| `delete_path`            | The path being deleted       |
 51| `move_path`              | Source and destination paths |
 52| `copy_path`              | Source and destination paths |
 53| `create_directory`       | The directory path           |
 54| `restore_file_from_disk` | The file paths               |
 55| `save_file`              | The file paths               |
 56| `fetch`                  | The URL                      |
 57| `web_search`             | The search query             |
 58
 59For MCP tools, use the format `mcp:<server>:<tool_name>`.
 60For example, a tool called `create_issue` on a server called `github` would be `mcp:github:create_issue`.
 61
 62## Configuration
 63
 64```json [settings]
 65{
 66  "agent": {
 67    "tool_permissions": {
 68      "default": "confirm",
 69      "tools": {
 70        "<tool_name>": {
 71          "default": "confirm",
 72          "always_allow": [{ "pattern": "...", "case_sensitive": false }],
 73          "always_deny": [{ "pattern": "...", "case_sensitive": false }],
 74          "always_confirm": [{ "pattern": "...", "case_sensitive": false }]
 75        }
 76      }
 77    }
 78  }
 79}
 80```
 81
 82### Options
 83
 84| Option           | Description                                                                    |
 85| ---------------- | ------------------------------------------------------------------------------ |
 86| `default`        | Fallback when no patterns match: `"confirm"` (default), `"allow"`, or `"deny"` |
 87| `always_allow`   | Patterns that auto-approve (unless deny or confirm also matches)               |
 88| `always_deny`    | Patterns that block immediately—highest priority, cannot be overridden         |
 89| `always_confirm` | Patterns that always prompt, even when `tool_permissions.default` is `"allow"` |
 90
 91### Pattern Syntax
 92
 93```json [settings]
 94{
 95  "agent": {
 96    "tool_permissions": {
 97      "tools": {
 98        "edit_file": {
 99          "always_allow": [
100            {
101              "pattern": "your-regex-here",
102              "case_sensitive": false
103            }
104          ]
105        }
106      }
107    }
108  }
109}
110```
111
112Patterns use Rust regex syntax.
113Matching is case-insensitive by default.
114
115## Rule Precedence
116
117From highest to lowest priority:
118
1191. **Built-in security rules**: Hardcoded protections (e.g., `rm -rf /`). Cannot be overridden.
1202. **`always_deny`**: Blocks matching actions
1213. **`always_confirm`**: Requires confirmation for matching actions
1224. **`always_allow`**: Auto-approves matching actions
1235. **Tool-specific `default`**: Per-tool fallback when no patterns match (e.g., `tools.terminal.default`)
1246. **Global `default`**: Falls back to `tool_permissions.default` when no tool-specific default is set
125
126## Global Auto-Approve
127
128To auto-approve all tool actions:
129
130```json [settings]
131{
132  "agent": {
133    "tool_permissions": {
134      "default": "allow"
135    }
136  }
137}
138```
139
140This bypasses confirmation prompts for most tools, but `always_deny`, `always_confirm`, built-in security rules, and paths inside Zed settings directories still prompt or block.
141
142## Shell Compatibility
143
144For the `terminal` tool, Zed parses chained commands (e.g., `echo hello && rm file`) to check each sub-command against your patterns.
145
146All supported shells work with tool permission patterns, including sh, bash, zsh, dash, fish, PowerShell 7+, pwsh, cmd, xonsh, csh, tcsh, Nushell, Elvish, and rc (Plan 9).
147
148## Writing Patterns
149
150- Use `\b` for word boundaries: `\brm\b` matches "rm" but not "storm"
151- Use `^` and `$` to anchor patterns to start/end of input
152- Escape special characters: `\.` for literal dot, `\\` for backslash
153
154<div class="warning">
155
156Test carefully—a typo in a deny pattern blocks legitimate actions.
157You can use the "Test Your Rules" checker, available in each individual tool page, to confirm whether a pattern is correctly falling in the desired condition.
158
159</div>
160
161## Built-in Security Rules
162
163Zed includes a small set of hardcoded security rules that **cannot be overridden** by any setting.
164These only apply to the **terminal** tool and block recursive deletion of critical directories:
165
166- `rm -rf /` and `rm -rf /*` — filesystem root
167- `rm -rf ~` and `rm -rf ~/*` — home directory
168- `rm -rf $HOME` / `rm -rf ${HOME}` (and `$HOME/*`) — home directory via environment variable
169- `rm -rf .` and `rm -rf ./*` — current directory
170- `rm -rf ..` and `rm -rf ../*` — parent directory
171
172These patterns catch any flag combination (e.g., `-fr`, `-rfv`, `-r -f`, `--recursive --force`) and are case-insensitive.
173They are checked against both the raw command and each parsed sub-command in chained commands (e.g., `ls && rm -rf /`).
174
175There are no other built-in rules.
176The default settings file ({#action zed::OpenDefaultSettings}) includes commented-out examples for protecting `.env` files, secrets directories, and private keys — you can uncomment or adapt these to suit your needs.
177
178## Permission Request in the UI
179
180When the agent requests permission, you'll see in the thread view a tool card with a menu that includes:
181
182- **Allow once** / **Deny once** — One-time decision
183- **Always for <tool>** — Sets a tool-level default to allow or deny
184- **Always for <pattern>** — Adds an `always_allow` or `always_deny` pattern (when a safe pattern can be extracted)
185
186Selecting "Always for <tool>" sets `tools.<tool>.default` to allow or deny.
187When a pattern can be safely extracted, selecting "Always for <pattern>" adds an `always_allow` or `always_deny` rule for that input.
188MCP tools only support the tool-level option.
189
190## Examples
191
192### Terminal: Auto-Approve Build Commands
193
194```json [settings]
195{
196  "agent": {
197    "tool_permissions": {
198      "tools": {
199        "terminal": {
200          "default": "confirm",
201          "always_allow": [
202            { "pattern": "^cargo\\s+(build|test|check|clippy|fmt)" },
203            { "pattern": "^npm\\s+(install|test|run|build)" },
204            { "pattern": "^git\\s+(status|log|diff|branch)" },
205            { "pattern": "^ls\\b" },
206            { "pattern": "^cat\\s" }
207          ],
208          "always_deny": [
209            { "pattern": "rm\\s+-rf\\s+(/|~)" },
210            { "pattern": "sudo\\s+rm" }
211          ],
212          "always_confirm": [
213            { "pattern": "sudo\\s" },
214            { "pattern": "git\\s+push" }
215          ]
216        }
217      }
218    }
219  }
220}
221```
222
223### File Editing: Protect Sensitive Files
224
225```json [settings]
226{
227  "agent": {
228    "tool_permissions": {
229      "tools": {
230        "edit_file": {
231          "default": "confirm",
232          "always_allow": [
233            { "pattern": "\\.(md|txt|json)$" },
234            { "pattern": "^src/" }
235          ],
236          "always_deny": [
237            { "pattern": "\\.env" },
238            { "pattern": "secrets?/" },
239            { "pattern": "\\.(pem|key)$" }
240          ]
241        }
242      }
243    }
244  }
245}
246```
247
248### Path Deletion: Block Critical Directories
249
250```json [settings]
251{
252  "agent": {
253    "tool_permissions": {
254      "tools": {
255        "delete_path": {
256          "default": "confirm",
257          "always_deny": [
258            { "pattern": "^/etc" },
259            { "pattern": "^/usr" },
260            { "pattern": "\\.git/?$" },
261            { "pattern": "node_modules/?$" }
262          ]
263        }
264      }
265    }
266  }
267}
268```
269
270### URL Fetching: Control External Access
271
272```json [settings]
273{
274  "agent": {
275    "tool_permissions": {
276      "tools": {
277        "fetch": {
278          "default": "confirm",
279          "always_allow": [
280            { "pattern": "docs\\.rs" },
281            { "pattern": "github\\.com" }
282          ],
283          "always_deny": [{ "pattern": "internal\\.company\\.com" }]
284        }
285      }
286    }
287  }
288}
289```
290
291### MCP Tools
292
293```json [settings]
294{
295  "agent": {
296    "tool_permissions": {
297      "tools": {
298        "mcp:github:create_issue": {
299          "default": "confirm"
300        },
301        "mcp:github:create_pull_request": {
302          "default": "confirm"
303        }
304      }
305    }
306  }
307}
308```