--- title: Permissions description: Control which actions require approval to run. --- OpenCode uses the `permission` config to decide whether a given action should run automatically, prompt you, or be blocked. As of `v1.1.1`, the legacy `tools` boolean config is deprecated and has been merged into `permission`. The old `tools` config is still supported for backwards compatibility. --- ## Actions Each permission rule resolves to one of: - `"allow"` — run without approval - `"ask"` — prompt for approval - `"deny"` — block the action --- ## Configuration You can set permissions globally (with `*`), and override specific tools. ```json title="opencode.json" { "$schema": "https://opencode.ai/config.json", "permission": { "*": "ask", "bash": "allow", "edit": "deny" } } ``` You can also set all permissions at once: ```json title="opencode.json" { "$schema": "https://opencode.ai/config.json", "permission": "allow" } ``` --- ## Granular Rules (Object Syntax) For most permissions, you can use an object to apply different actions based on the tool input. ```json title="opencode.json" { "$schema": "https://opencode.ai/config.json", "permission": { "bash": { "*": "ask", "git *": "allow", "npm *": "allow", "rm *": "deny", "grep *": "allow" }, "edit": { "*": "deny", "packages/web/src/content/docs/*.mdx": "allow" } } } ``` Rules are evaluated by pattern match, with the **last matching rule winning**. A common pattern is to put the catch-all `"*"` rule first, and more specific rules after it. ### Wildcards Permission patterns use simple wildcard matching: - `*` matches zero or more of any character - `?` matches exactly one character - All other characters match literally --- ## Available Permissions OpenCode permissions are keyed by tool name, plus a couple of safety guards: - `read` — reading a file (matches the file path) - `edit` — all file modifications (covers `edit`, `write`, `patch`, `multiedit`) - `glob` — file globbing (matches the glob pattern) - `grep` — content search (matches the regex pattern) - `list` — listing files in a directory (matches the directory path) - `bash` — running shell commands (matches parsed commands like `git status --porcelain`) - `task` — launching subagents (matches the subagent type) - `skill` — loading a skill (matches the skill name) - `lsp` — running LSP queries (currently non-granular) - `todoread`, `todowrite` — reading/updating the todo list - `webfetch` — fetching a URL (matches the URL) - `websearch`, `codesearch` — web/code search (matches the query) - `external_directory` — triggered when a tool touches paths outside the project working directory - `doom_loop` — triggered when the same tool call repeats 3 times with identical input --- ## Defaults If you don’t specify anything, OpenCode starts from permissive defaults: - Most permissions default to `"allow"`. - `doom_loop` and `external_directory` default to `"ask"`. - `read` is `"allow"`, but `.env` files are denied by default: ```json title="opencode.json" { "permission": { "read": { "*": "allow", "*.env": "deny", "*.env.*": "deny", "*.env.example": "allow" } } } ``` --- ## What “Ask” Does When OpenCode prompts for approval, the UI offers three outcomes: - `once` — approve just this request - `always` — approve future requests matching the suggested patterns (for the rest of the current OpenCode session) - `reject` — deny the request The set of patterns that `always` would approve is provided by the tool (for example, bash approvals typically whitelist a safe command prefix like `git status*`). --- ## Agents You can override permissions per agent. Agent permissions are merged with the global config, and agent rules take precedence. [Learn more](/docs/agents#permissions) about agent permissions. :::note Refer to the [Granular Rules (Object Syntax)](#granular-rules-object-syntax) section above for more detailed pattern matching examples. ::: ```json title="opencode.json" { "$schema": "https://opencode.ai/config.json", "permission": { "bash": { "*": "ask", "git *": "allow", "git commit *": "deny", "git push *": "deny", "grep *": "allow" } }, "agent": { "build": { "permission": { "bash": { "*": "ask", "git *": "allow", "git commit *": "ask", "git push *": "deny", "grep *": "allow" } } } } } ``` You can also configure agent permissions in Markdown: ```markdown title="~/.config/opencode/agents/review.md" --- description: Code review without edits mode: subagent permission: edit: deny bash: ask webfetch: deny --- Only analyze code and suggest changes. ``` :::tip Use pattern matching for commands with arguments. `"grep *"` allows `grep pattern file.txt`, while `"grep"` alone would block it. Commands like `git status` work for default behavior but require explicit permission (like `"git status *"`) when arguments are passed. :::