OpenCode Permission Configuration

OpenCode's permission system controls which operations can run automatically, which require your manual approval, and which are directly blocked. Properly configuring permissions lets AI complete tasks efficiently while preventing accidental operations that could damage code or leak sensitive files.

Starting from v1.1.1, the oldtoolsboolean configuration has been deprecated and merged intopermission. The old configuration is still supported for backward compatibility, but it is recommended to migrate to the newpermissionsyntax.


Three Permission Actions

Each permission rule ultimately resolves to one of the following three actions:

Action Effect Applicable scenarios
"allow" Runs automatically without approval Low-risk, high-frequency operations, such as reading files and running tests
"ask" Shows an approval prompt for you to decide whether to allow Operations with some risk, such as writing files and executing scripts
"deny" Blocked directly, neither executed nor prompted Dangerous operations that are explicitly disallowed, such as deleting files and pushing code

Basic Configuration

Permission configuration is written under the repository root directory (or user configuration directory) in theopencode.jsonfile, usingpermissionfield to configure.

1. Set all permissions globally

The simplest way: use a single string to set permissions for all operations at once. Suitable for quick start or temporary debugging:

Example

{
  "$schema": "https://opencode.ai/config.json",
"permission": "allow" // All operations run automatically without any prompts (suitable for local development, when fully trusting AI)
}

2. Configure by tool name

Using object syntax, you can specify permissions for different tools separately."*"is a wildcard, meaning it matches all operations, usually used as the fallback default value:

Example

{
  "$schema": "https://opencode.ai/config.json",
  "permission": {
"*": "ask", // Fallback rule: all tools not individually configured default to showing a prompt
"bash": "allow", // bash (executing Shell commands): allow directly, no prompt
"edit": "deny" // edit (modifying files): block directly
  }
}

Fine-grained rules (object syntax)

For most permissions, in addition to setting a unified action, you can also useobject syntaxto apply different rules based on the tool's specific input. For example, forbashtools, you can distinguish which commands are allowed, which require approval, and which are directly rejected:

Example

{
  "$schema": "https://opencode.ai/config.json",
  "permission": {
    "bash": {
"*": "ask", // Fallback: all bash commands require approval by default
"git *": "allow", // Commands starting with git (e.g., git status, git log) are allowed directly
"npm *": "allow", // Commands starting with npm (e.g., npm install, npm run build) are allowed directly
"grep *": "allow", // grep search commands are allowed directly
"rm *": "deny" // rm delete commands are directly blocked (to prevent accidental file deletion)
    },
    "edit": {
"*": "deny", // Block all file edits by default
"packages/web/src/content/docs/*.mdx": "allow" // Only allow editing .mdx files under the docs directory
    }
  }
}

Rule matching order: the last matched rule takes precedence.It is recommended to put the wildcard"*"rule at the top as the default value, and place more specific rules after it to override it. This way, the more specific a rule is, the higher its priority, making the logic clear and less error-prone.


Wildcard rules

Permission patterns support simple wildcard matching, with the following rules:

Wildcard Meaning Example
* Matches zero or more arbitrary characters (not crossing directories) git *Matchesgit status、git log --onelinewait
** Matches any path across directories ~/projects/**Matches all files and subdirectories under projects
? Exactly matches one arbitrary character file?.txtMatchesfile1.txt、fileA.txt
Other characters Matches exactly by literal value git statusOnly matchesgit status, does not match variants with parameters

Note:For commands with parameters, be sure to append at the end*. For example"grep *"can matchgrep pattern file.txt, while writing alone"grep"only matches bare commands without any parameters, which will almost never be matched in actual execution.

Home directory expansion

At the beginning of a pattern, you can use~or$HOMEto refer to the current user's home directory, and OpenCode will automatically expand it to the full path:

Example

// The following three forms have the same effect, all expand to /Users/username/projects/* (path varies by system)
"~/projects/*"
"$HOME/projects/*"
"/Users/username/projects/*" // Writing the absolute path directly also works, but is not recommended (not portable enough)

External directory permissions (external_directory)

By default, OpenCode only allows tools to accessthe working directory at startupand its subdirectories. If you need to access paths outside the project directory (e.g., another project or a shared configuration directory), you must useexternal_directoryexplicit authorization.

Home directory expansion (~/...) is only a pathshorthand notation, and does not automatically authorize access to that path. Paths outside the working directory must still go throughexternal_directoryto be allowed.

1. Allow access to external directories

Example

{
  "$schema": "https://opencode.ai/config.json",
  "permission": {
    "external_directory": {
"~/projects/personal/**": "allow" // Allow access to all files and subdirectories under ~/projects/personal/
// ** matches subpaths at any level
    }
  }
}

2. Allow reading but forbid editing

Byexternal_directoryAuthorized directories inherit the default permissions of the current workspace. Sincereaddefaults to"allow", after authorization, files under that directory can be read. If you need to further restrict a certain operation (e.g., allow reading but forbid editing), you can add extra rules:

Example

{
  "$schema": "https://opencode.ai/config.json",
  "permission": {
    "external_directory": {
"~/projects/personal/**": "allow" // Step 1: Grant access to this external directory
    },
    "edit": {
"~/projects/personal/**": "deny" // Step 2: Add an overriding rule on this directory, allowing reading but forbidding editing
    }
  }
}

All available permission items

OpenCode's permissions use tool names as keys, covering all types including file operations, command execution, and network access:

Permission item Controlled operation Pattern matching content Default value
read Read file contents File path (e.g.,src/index.js) allow(.envfiles excluded)
edit All file modifications, covering edit, write, patch, and multiedit File path allow
glob File glob search (e.g., find all.tsfiles) Glob pattern (e.g.,**/*.ts) allow
grep Search for text in file contents Regular expression pattern allow
list List files in a directory Directory path allow
bash Run shell command Parsed full command (e.g.,git status --porcelain) allow
task Start sub-agent Sub-agent type name allow
skill Load skill Skill name allow
lsp Run LSP language service query Fine-grained configuration is currently not supported allow
webfetch Fetch network URL content Full URL (e.g.,https://example.com/api) allow
websearch Web search Search query string allow
codesearch Code search Search query string allow
external_directory Access paths outside the working directory External directory path ask
doom_loop Triggered when the same tool is called 3 times repeatedly with the same input (prevents the AI from getting stuck in a loop) — ask

Default permission description

If you have not configured any permissions, OpenCode uses the following built-in defaults:

  • Most tool permissions default to"allow", meaning they run automatically without prompting
  • doom_loopandexternal_directoryDefaults to"ask", requiring manual approval
  • readReading all files is allowed by default, but.envrelated files have built-in protection:

Example

// OpenCode's built-in default read rules (no manual configuration needed, for reference only)
{
  "permission": {
    "read": {
"*": "allow", // Allow reading all files by default
"*.env": "deny", // Block reading .env files (prevent leaking database passwords, API keys, etc.)
"*.env.*": "deny", // Block reading variants such as .env.local, .env.production
"*.env.example": "allow" // Allow reading .env.example (sample file, no real secrets)
    }
  }
}

Three options in the approval prompt

When an operation's permission is"ask", OpenCode pops up an approval prompt offering the following three choices:

Option Effect Applicable scenario
once (this time only) Only approve this request; the same operation next time will still prompt Temporarily allow an operation without permanently enabling it
always (always allow) Add the operation's matching pattern to the whitelist; no more prompts for the rest of the current session Confirm that a type of operation is safe and want it to pass automatically in this session
reject (refuse) Reject this request; the operation will not be executed The operation appears risky and you explicitly do not want it executed

Selectingalwaysafter, OpenCode will have the tool automatically provide a suggested whitelist pattern (e.g., after approvinggit status, it will usually addgit status*to the whitelist).The whitelist is only valid for the current session and will be reset after restarting OpenCode.


Configure permissions separately for agents

If your workflow uses multiple agents, you can override the permission configuration for each agent individually. Agent permissions are merged with the global configuration, andagent rules take priority over global rules。

1. Configure agent permissions in opencode.json

Example

{
  "$schema": "https://opencode.ai/config.json",
  "permission": {
// Global permissions: git operations allowed, but commit and push forbidden
    "bash": {
      "*": "ask",
      "git *": "allow",
      "git commit *": "deny",
      "git push *": "deny",
      "grep *": "allow"
    }
  },
  "agent": {
"build": { // Agent named build
      "permission": {
        "bash": {
          "*": "ask",
          "git *": "allow",
"git commit *": "ask", // Overrides global: build agent allows commit, but requires approval
"git push *": "deny", // Inherits global: push still forbidden
          "grep *": "allow"
        }
      }
    }
  }
}

2. Configure agent permissions in Markdown files

Agents can also be configured via Markdown files, with permissions written in the YAML Front Matter at the top of the file (---the part in between):

Example

# File path: ~/.config/opencode/agents/review.md
---
description
: Code review agent (only analyzes code, makes no changes)
mode
: subagent
permission
:
  edit
: deny        # Forbid all file editing
  bash
: ask         # bash commands require approval
  webfetch
: deny    # Forbid access to external URLs
---

Only analyze code and suggest changes.
# Below is the agent's system prompt, describing the agent's responsibilities and behavioral norms

Practical configuration examples

Example 1: Conservative mode (all operations require approval)

Suitable for those new to OpenCode or when working on important projects; all operations require manual confirmation:

Example

{
  "$schema": "https://opencode.ai/config.json",
  "permission": {
"*": "ask" // All operations of all tools trigger approval prompts
  }
}

Example 2: Common development configuration (read operations allowed, write operations require approval)

Suitable for daily development: allows the AI to freely read and search code, but requires confirmation when modifying files and executing commands:

Example

{
  "$schema": "https://opencode.ai/config.json",
  "permission": {
"*": "ask", // Fallback: tools not individually configured require approval by default
"read": "allow", // Read files: allow directly
"glob": "allow", // File glob search: allow directly
"grep": "allow", // Content search: allow directly
"list": "allow", // List directories: allow directly
    "bash": {
"*": "ask", // bash commands require approval by default
"git status *": "allow", // View git status: allow
"git log *": "allow", // View git log: allow
"git diff *": "allow", // View git diff: allow
"npm run *": "allow", // Run npm scripts: allow
"npm test *": "allow", // Run tests: allow
"rm *": "deny" // Delete files: block directly
    }
  }
}

Example 3: Allow access to multiple project directories

When the AI needs to work across multiple project directories, grant access to external directories:

Example

{
  "$schema": "https://opencode.ai/config.json",
  "permission": {
    "external_directory": {
"~/projects/personal/**": "allow", // Allow access to personal project directories
"~/projects/work/**": "allow", // Allow access to work project directories
"~/dotfiles/**": "allow" // Allow access to the dotfiles directory
    },
    "edit": {
"~/dotfiles/**": "deny" // Even if access to dotfiles is allowed, editing is forbidden (read-only)
    }
  }
}
Other extensions