# Tool Permissions Configure which [Agent Panel](./agent-panel.md) tools run automatically and which require your approval. For a list of available tools, [see the Tools page](./tools.md). > **Note:** In Zed v0.224.0 and above, tool approval is controlled by `agent.tool_permissions.default`. > In earlier versions, it was controlled by the `agent.always_allow_tool_actions` boolean (default `false`). ## Quick Start Use Zed's Settings Editor to [configure tool permissions](zed://settings/agent.tool_permissions), or add rules directly to your settings file: ```json [settings] { "agent": { "tool_permissions": { "default": "allow", "tools": { "terminal": { "default": "confirm", "always_allow": [ { "pattern": "^cargo\\s+(build|test|check)" }, { "pattern": "^npm\\s+(install|test|run)" } ], "always_confirm": [{ "pattern": "sudo\\s+/" }] } } } } } ``` This example auto-approves `cargo` and `npm` commands in the terminal tool, while requiring manual confirmation on a case-by-case basis for `sudo` commands. Non-terminal commands follow the global `"default": "allow"` setting, but tool-specific defaults and `always_confirm` rules can still prompt. ## How It Works The `tool_permissions` setting lets you customize tool permissions by specifying regex patterns that: - **Auto-approve** actions you trust - **Auto-deny** dangerous actions (blocked even when `tool_permissions.default` is set to `"allow"`) - **Always confirm** sensitive actions regardless of other settings ## Supported Tools | Tool | Input Matched Against | | ------------------ | ------------------------------------------------ | | `terminal` | The shell command string | | `edit_file` | The file path | | `write_file` | The file path | | `delete_path` | The path being deleted | | `move_path` | Source and destination paths | | `copy_path` | Source and destination paths | | `create_directory` | The directory path | | `fetch` | The URL | | `search_web` | The search query | | `skill` | The absolute path to the skill's `SKILL.md` file | For [MCP tools](./mcp.md), use the format `mcp::`. For example, a tool called `create_issue` on a server called `github` would be `mcp:github:create_issue`. For model-invoked [Skills](./skills.md), use the `skill` tool. A user-invoked `/skill-name` slash command does not prompt again because you explicitly invoked the skill. ## Configuration ```json [settings] { "agent": { "tool_permissions": { "default": "confirm", "tools": { "": { "default": "confirm", "always_allow": [{ "pattern": "...", "case_sensitive": false }], "always_deny": [{ "pattern": "...", "case_sensitive": false }], "always_confirm": [{ "pattern": "...", "case_sensitive": false }] } } } } } ``` ### Options | Option | Description | | ---------------- | ------------------------------------------------------------------------------ | | `default` | Fallback when no patterns match: `"confirm"` (default), `"allow"`, or `"deny"` | | `always_allow` | Patterns that auto-approve (unless deny or confirm also matches) | | `always_deny` | Patterns that block immediately—highest priority, cannot be overridden | | `always_confirm` | Patterns that always prompt, even when `tool_permissions.default` is `"allow"` | ### Pattern Syntax ```json [settings] { "agent": { "tool_permissions": { "tools": { "edit_file": { "always_allow": [ { "pattern": "your-regex-here", "case_sensitive": false } ] } } } } } ``` Patterns use Rust regex syntax. Matching is case-insensitive by default. ## Rule Precedence From highest to lowest priority: 1. **Built-in security rules**: Hardcoded protections (e.g., `rm -rf /`). Cannot be overridden. 2. **`always_deny`**: Blocks matching actions 3. **`always_confirm`**: Requires confirmation for matching actions 4. **`always_allow`**: Auto-approves matching actions 5. **Tool-specific `default`**: Per-tool fallback when no patterns match (e.g., `tools.terminal.default`) 6. **Global `default`**: Falls back to `tool_permissions.default` when no tool-specific default is set ## Global Auto-Approve To auto-approve all tool actions: ```json [settings] { "agent": { "tool_permissions": { "default": "allow" } } } ``` This 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. ## Shell Compatibility For the `terminal` tool, Zed parses chained commands (e.g., `echo hello && rm file`) to check each sub-command against your patterns. All 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). ## Writing Patterns - Use `\b` for word boundaries: `\brm\b` matches "rm" but not "storm" - Use `^` and `$` to anchor patterns to start/end of input - Escape special characters: `\.` for literal dot, `\\` for backslash
Test carefully—a typo in a deny pattern blocks legitimate actions. You 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.
## Built-in Security Rules Zed includes a small set of hardcoded security rules that **cannot be overridden** by any setting. These only apply to the **terminal** tool and block recursive deletion of critical directories: - `rm -rf /` and `rm -rf /*` — filesystem root - `rm -rf ~` and `rm -rf ~/*` — home directory - `rm -rf $HOME` / `rm -rf ${HOME}` (and `$HOME/*`) — home directory via environment variable - `rm -rf .` and `rm -rf ./*` — current directory - `rm -rf ..` and `rm -rf ../*` — parent directory These patterns catch any flag combination (e.g., `-fr`, `-rfv`, `-r -f`, `--recursive --force`) and are case-insensitive. They are checked against both the raw command and each parsed sub-command in chained commands (e.g., `ls && rm -rf /`). There are no other built-in rules. The 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. ## Permission Request in the UI When the agent requests permission, you'll see in the thread view a tool card with a menu that includes: - **Allow once** / **Deny once** — One-time decision - **Always for ** — Sets a tool-level default to allow or deny - **Always for ** — Adds an `always_allow` or `always_deny` pattern (when a safe pattern can be extracted) Selecting "Always for " sets `tools..default` to allow or deny. When a pattern can be safely extracted, selecting "Always for " adds an `always_allow` or `always_deny` rule for that input. MCP tools only support the tool-level option. ## Examples ### Terminal: Auto-Approve Build Commands ```json [settings] { "agent": { "tool_permissions": { "tools": { "terminal": { "default": "confirm", "always_allow": [ { "pattern": "^cargo\\s+(build|test|check|clippy|fmt)" }, { "pattern": "^npm\\s+(install|test|run|build)" }, { "pattern": "^git\\s+(status|log|diff|branch)" }, { "pattern": "^ls\\b" }, { "pattern": "^cat\\s" } ], "always_deny": [ { "pattern": "rm\\s+-rf\\s+(/|~)" }, { "pattern": "sudo\\s+rm" } ], "always_confirm": [ { "pattern": "sudo\\s" }, { "pattern": "git\\s+push" } ] } } } } } ``` ### File Editing: Protect Sensitive Files ```json [settings] { "agent": { "tool_permissions": { "tools": { "edit_file": { "default": "confirm", "always_allow": [ { "pattern": "\\.(md|txt|json)$" }, { "pattern": "^src/" } ], "always_deny": [ { "pattern": "\\.env" }, { "pattern": "secrets?/" }, { "pattern": "\\.(pem|key)$" } ] } } } } } ``` ### Path Deletion: Block Critical Directories ```json [settings] { "agent": { "tool_permissions": { "tools": { "delete_path": { "default": "confirm", "always_deny": [ { "pattern": "^/etc" }, { "pattern": "^/usr" }, { "pattern": "\\.git/?$" }, { "pattern": "node_modules/?$" } ] } } } } } ``` ### URL Fetching: Control External Access ```json [settings] { "agent": { "tool_permissions": { "tools": { "fetch": { "default": "confirm", "always_allow": [ { "pattern": "docs\\.rs" }, { "pattern": "github\\.com" } ], "always_deny": [{ "pattern": "internal\\.company\\.com" }] } } } } } ``` ### MCP Tools ```json [settings] { "agent": { "tool_permissions": { "tools": { "mcp:github:create_issue": { "default": "confirm" }, "mcp:github:create_pull_request": { "default": "confirm" } } } } } ``` ### Skills Patterns for the `skill` tool match against the absolute path to the skill's `SKILL.md` file, not the skill name. ```json [settings] { "agent": { "tool_permissions": { "tools": { "skill": { "default": "confirm", "always_allow": [{ "pattern": "/code-review/SKILL\\.md$" }] } } } } } ``` To prevent the model from invoking a skill at all, set `disable-model-invocation: true` in that skill's `SKILL.md`. See [Skills](./skills.md#disable-model-invocation).