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| `write_file` | The file path |
51| `delete_path` | The path being deleted |
52| `move_path` | Source and destination paths |
53| `copy_path` | Source and destination paths |
54| `create_directory` | The directory path |
55| `fetch` | The URL |
56| `search_web` | The search query |
57
58For MCP tools, use the format `mcp:<server>:<tool_name>`.
59For example, a tool called `create_issue` on a server called `github` would be `mcp:github:create_issue`.
60
61## Configuration
62
63```json [settings]
64{
65 "agent": {
66 "tool_permissions": {
67 "default": "confirm",
68 "tools": {
69 "<tool_name>": {
70 "default": "confirm",
71 "always_allow": [{ "pattern": "...", "case_sensitive": false }],
72 "always_deny": [{ "pattern": "...", "case_sensitive": false }],
73 "always_confirm": [{ "pattern": "...", "case_sensitive": false }]
74 }
75 }
76 }
77 }
78}
79```
80
81### Options
82
83| Option | Description |
84| ---------------- | ------------------------------------------------------------------------------ |
85| `default` | Fallback when no patterns match: `"confirm"` (default), `"allow"`, or `"deny"` |
86| `always_allow` | Patterns that auto-approve (unless deny or confirm also matches) |
87| `always_deny` | Patterns that block immediately—highest priority, cannot be overridden |
88| `always_confirm` | Patterns that always prompt, even when `tool_permissions.default` is `"allow"` |
89
90### Pattern Syntax
91
92```json [settings]
93{
94 "agent": {
95 "tool_permissions": {
96 "tools": {
97 "edit_file": {
98 "always_allow": [
99 {
100 "pattern": "your-regex-here",
101 "case_sensitive": false
102 }
103 ]
104 }
105 }
106 }
107 }
108}
109```
110
111Patterns use Rust regex syntax.
112Matching is case-insensitive by default.
113
114## Rule Precedence
115
116From highest to lowest priority:
117
1181. **Built-in security rules**: Hardcoded protections (e.g., `rm -rf /`). Cannot be overridden.
1192. **`always_deny`**: Blocks matching actions
1203. **`always_confirm`**: Requires confirmation for matching actions
1214. **`always_allow`**: Auto-approves matching actions
1225. **Tool-specific `default`**: Per-tool fallback when no patterns match (e.g., `tools.terminal.default`)
1236. **Global `default`**: Falls back to `tool_permissions.default` when no tool-specific default is set
124
125## Global Auto-Approve
126
127To auto-approve all tool actions:
128
129```json [settings]
130{
131 "agent": {
132 "tool_permissions": {
133 "default": "allow"
134 }
135 }
136}
137```
138
139This 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.
140
141## Shell Compatibility
142
143For the `terminal` tool, Zed parses chained commands (e.g., `echo hello && rm file`) to check each sub-command against your patterns.
144
145All 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).
146
147## Writing Patterns
148
149- Use `\b` for word boundaries: `\brm\b` matches "rm" but not "storm"
150- Use `^` and `$` to anchor patterns to start/end of input
151- Escape special characters: `\.` for literal dot, `\\` for backslash
152
153<div class="warning">
154
155Test carefully—a typo in a deny pattern blocks legitimate actions.
156You 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.
157
158</div>
159
160## Built-in Security Rules
161
162Zed includes a small set of hardcoded security rules that **cannot be overridden** by any setting.
163These only apply to the **terminal** tool and block recursive deletion of critical directories:
164
165- `rm -rf /` and `rm -rf /*` — filesystem root
166- `rm -rf ~` and `rm -rf ~/*` — home directory
167- `rm -rf $HOME` / `rm -rf ${HOME}` (and `$HOME/*`) — home directory via environment variable
168- `rm -rf .` and `rm -rf ./*` — current directory
169- `rm -rf ..` and `rm -rf ../*` — parent directory
170
171These patterns catch any flag combination (e.g., `-fr`, `-rfv`, `-r -f`, `--recursive --force`) and are case-insensitive.
172They are checked against both the raw command and each parsed sub-command in chained commands (e.g., `ls && rm -rf /`).
173
174There are no other built-in rules.
175The 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.
176
177## Permission Request in the UI
178
179When the agent requests permission, you'll see in the thread view a tool card with a menu that includes:
180
181- **Allow once** / **Deny once** — One-time decision
182- **Always for <tool>** — Sets a tool-level default to allow or deny
183- **Always for <pattern>** — Adds an `always_allow` or `always_deny` pattern (when a safe pattern can be extracted)
184
185Selecting "Always for <tool>" sets `tools.<tool>.default` to allow or deny.
186When a pattern can be safely extracted, selecting "Always for <pattern>" adds an `always_allow` or `always_deny` rule for that input.
187MCP tools only support the tool-level option.
188
189## Examples
190
191### Terminal: Auto-Approve Build Commands
192
193```json [settings]
194{
195 "agent": {
196 "tool_permissions": {
197 "tools": {
198 "terminal": {
199 "default": "confirm",
200 "always_allow": [
201 { "pattern": "^cargo\\s+(build|test|check|clippy|fmt)" },
202 { "pattern": "^npm\\s+(install|test|run|build)" },
203 { "pattern": "^git\\s+(status|log|diff|branch)" },
204 { "pattern": "^ls\\b" },
205 { "pattern": "^cat\\s" }
206 ],
207 "always_deny": [
208 { "pattern": "rm\\s+-rf\\s+(/|~)" },
209 { "pattern": "sudo\\s+rm" }
210 ],
211 "always_confirm": [
212 { "pattern": "sudo\\s" },
213 { "pattern": "git\\s+push" }
214 ]
215 }
216 }
217 }
218 }
219}
220```
221
222### File Editing: Protect Sensitive Files
223
224```json [settings]
225{
226 "agent": {
227 "tool_permissions": {
228 "tools": {
229 "edit_file": {
230 "default": "confirm",
231 "always_allow": [
232 { "pattern": "\\.(md|txt|json)$" },
233 { "pattern": "^src/" }
234 ],
235 "always_deny": [
236 { "pattern": "\\.env" },
237 { "pattern": "secrets?/" },
238 { "pattern": "\\.(pem|key)$" }
239 ]
240 }
241 }
242 }
243 }
244}
245```
246
247### Path Deletion: Block Critical Directories
248
249```json [settings]
250{
251 "agent": {
252 "tool_permissions": {
253 "tools": {
254 "delete_path": {
255 "default": "confirm",
256 "always_deny": [
257 { "pattern": "^/etc" },
258 { "pattern": "^/usr" },
259 { "pattern": "\\.git/?$" },
260 { "pattern": "node_modules/?$" }
261 ]
262 }
263 }
264 }
265 }
266}
267```
268
269### URL Fetching: Control External Access
270
271```json [settings]
272{
273 "agent": {
274 "tool_permissions": {
275 "tools": {
276 "fetch": {
277 "default": "confirm",
278 "always_allow": [
279 { "pattern": "docs\\.rs" },
280 { "pattern": "github\\.com" }
281 ],
282 "always_deny": [{ "pattern": "internal\\.company\\.com" }]
283 }
284 }
285 }
286 }
287}
288```
289
290### MCP Tools
291
292```json [settings]
293{
294 "agent": {
295 "tool_permissions": {
296 "tools": {
297 "mcp:github:create_issue": {
298 "default": "confirm"
299 },
300 "mcp:github:create_pull_request": {
301 "default": "confirm"
302 }
303 }
304 }
305 }
306}
307```