YouTip LogoYouTip

Opencode Permissions

OpenCode Permission Configuration |

OpenCode's permission system is used to control which operations can run automatically, which require manual approval from you, and which will be blocked outright. Properly configuring permissions allows the AI to efficiently complete tasks while preventing accidental operations that could damage code or leak sensitive files.

Starting from v1.1.1, the old `tools` boolean configuration has been deprecated and merged into `permission`. The old configuration is still supported for backward compatibility, but it is recommended to migrate to the new `permission` syntax.


Three Permission Actions

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

Action Effect Use Case
"allow" No approval needed, runs automatically Low-risk, high-frequency operations like reading files or running tests
"ask" Pops up an approval prompt for you to decide whether to allow Operations with some risk, such as writing files or executing scripts
"deny" Blocks outright, neither executes nor prompts Clearly disallowed dangerous operations, such as deleting files or pushing code

Basic Configuration

Permission configurations are written in the opencode.json file located at the root of your repository (or user config directory) using the permission field.

1. Set All Permissions Globally

The simplest way: set all operation permissions with a single string. 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 or when fully trusting the AI)
}

2. Configure by Tool Name

Using object notation allows specifying permissions for different tools separately. "*" is a wildcard matching all operations, typically used as a fallback default:

Example

{
 "$schema": "https://opencode.ai/config.json",

 "permission": {
 "*": "ask", // Fallback rule: all unconfigured tools default to prompting
 "bash": "allow",  // bash (executing shell commands): directly allowed, no prompt
 "edit": "deny"  // edit (modifying files): blocked outright
 }
}

Fine-Grained Rules (Object Syntax)

For most permissions, besides setting a uniform action, you can also use the object syntax to apply different rules based on specific input content of the tool. For example, for the bash tool, you can distinguish which commands are allowed, which need approval, and which are denied outright:

Example

{
 "$schema": "https://opencode.ai/config.json",

 "permission": {
 "bash": {
 "*": "ask", // Fallback: all bash commands default to requiring approval
 "git *": "allow", // Commands starting with git (e.g., git status, git log) allowed directly
 "npm *": "allow", // Commands starting with npm (e.g., npm install, npm run build) allowed directly
 "grep *": "allow",  // Grep search commands allowed directly
 "rm *": "deny"  // rm delete commands blocked outright (to prevent accidental file deletion)
 },
 "edit": {
 "*": "deny", // Default to blocking all file edits
 "packages/web/src/content/docs/*.mdx": "allow"  // Only allow editing .mdx files under docs directory
 }
 }
}

Rule Matching Order: Last matched rule takes precedence. It is recommended to place the wildcard "*" rule first as a default value, with more specific rules placed later to override it. This way, more specific rules take higher priority, making 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 * matches git status, git log --oneline, etc.
** Matches arbitrary paths across directories ~/projects/** matches all files and subdirectories under projects
? Matches exactly one arbitrary character file?.txt matches file1.txt, fileA.txt
Other Characters Match literally git status only matches git status, not variants with parameters

Note: For commands with parameters, always add * at the end. For example, "grep *" matches grep pattern file.txt, while just writing "grep" only matches the bare command without parameters, which rarely matches in practice.

Home Directory Expansion

In patterns, you can use ~ or $HOME at the beginning to reference the current user's home directory. OpenCode will automatically expand it to the full path:

Example

// The following three forms have the same effect, all expanding to /Users/username/projects/* (path varies by system)

"~/projects/*"

"$HOME/projects/*"

"/Users/username/projects/*" // Absolute paths work too, but not recommended (less portable)

External Directory Permissions (external_directory)

By default, OpenCode only allows tools to access the working directory where it was started and its subdirectories. If you need to access paths outside the project directory (e.g., another project or shared config directory), you must explicitly authorize via external_directory.

Home directory expansion (~/...) is merely a shorthand for path writing and does not automatically grant access to that path. Paths outside the working directory still require explicit allowance through external_directory.

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 arbitrary nested subpaths
 }
 }
}

2. Allow Reading but Deny Editing

Directories authorized by external_directory inherit the default permissions of the current workspace. Since read defaults to "allow", files under these directories can be read after authorization. To further restrict certain operations (e.g., allow reading but prohibit editing), additional rules can be layered:

Example

{
 "$schema": "https://opencode.ai/config.json",

 "permission": {
 "external_directory": {
 "~/projects/personal/**": "allow" // Step 1: Authorize access to the external directory
 },
 "edit": {
 "~/projects/personal/**": "deny"  // Step 2: Overlay rules on this directory to allow reading but block editing
 }
 }
}

All Available Permission Items

OpenCode’s permissions are keyed by tool names, covering all types including file operations, command execution, network access, etc.:

Permission Item Controlled Operations Pattern Matching Content Default Value
read Reading file contents File paths (e.g., src/index.js) allow (except .env files)
edit All file modifications, including edit, write, patch, multiedit File paths allow
glob File wildcard searches (e.g., find all .ts files) Wildcard patterns (e.g., **/*.ts) allow
grep Search text within file contents Regular expression patterns allow
list List files in a directory Directory paths allow
bash Run shell commands Parsed full command (e.g., git status --porcelain) allow
task Launch sub-agents Sub-agent type names allow
skill Load skills Skill names allow
lsp Run LSP language service queries Currently not configurable granularly allow
webfetch Fetch content from URLs Full URL (e.g., https://example.com/api) allow
websearch Web search Search query strings allow
codesearch Code search Search query strings allow
external_directory Access paths outside the working directory External directory paths ask
doom_loop Triggered when the same tool is called with identical input 3 times (prevents AI infinite loops) β€” ask

Default Permission Explanation

If you do not configure any permissions, OpenCode uses the following built-in defaults:

  • Most tool permissions default to "allow", meaning they run automatically without prompts
  • doom_loop and external_directory default to "ask", requiring manual approval
  • read allows reading all files by default, but includes built-in protection for .env-related files:

Example

// Built-in read default rules in OpenCode (no need to configure manually, for reference only)

{
 "permission": {
 "read": {
 "*": "allow",  // Default to allowing reading all files
 "*.env": "deny", // Block reading .env files (to prevent leaking database passwords, API keys, etc.)
 "*.env.*": "deny", // Block reading .env.local, .env.production, etc.
 "*.env.example": "allow" // Allow reading .env.example (example file, no real secrets)
 }
 }
}

Three Options for Approval Prompts

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

Option Effect Use Case
once (Just Once) Approve only this request; next time the same operation will prompt again Temporarily allow an operation without permanently opening it
always (Always Allow) Adds the matching pattern of this operation to the whitelist, no more prompts for the rest of the session Confirm a class of operations is safe and want them to auto-pass in this session
reject (Reject) Reject this request, operation won't execute Detect risk in the operation and clearly don’t want it executed

After choosing always, OpenCode will automatically suggest a whitelist pattern (e.g., after approving git status, it usually adds git status* to the whitelist). The whitelist is only valid for the current session and resets upon restarting OpenCode.


Configuring Permissions Separately for Agents

If your workflow uses multiple agents, you can override permission configurations for each agent individually. Agent permissions merge with global settings, and agent rules take precedence 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 denied
 "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", // Override global: build agent allows commit but requires approval
 "git push *": "deny",  // Inherit global: still denies push
 "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 (between ---):

Example

# File Path: ~/.config/opencode/agents/review.md

---

 description: Code review agent (only analyzes code, makes no modifications)
 mode: subagent
 permission:
 edit: deny # Prohibit all file edits
 bash: ask # Bash commands require approval
 webfetch: deny # Prohibit accessing external URLs

---

Only analyze code and suggest changes.

# Below are the system prompts for this agent, describing its responsibilities and behavior norms

Practical Configuration Examples

Example 1: Conservative Mode (All Operations Require Approval)

Suitable for first-time users of OpenCode or working on important projects, where all operations require manual confirmation:

Example

{
 "$schema": "https://opencode.ai/config.json",

 "permission": {
 "*": "ask" // Prompt for approval for all operations of all tools
 }
}

Example 2: Development Common Configuration (Read Allowed, Write Approved)

Suitable for daily development: allow AI to freely read and search code, but confirm before modifying files or executing commands:

Example

{
 "$schema": "https://opencode.ai/config.json",

 "permission": {
 "*": "ask", // Fallback: unconfigured tools default to prompting
 "read": "allow",  // Reading files: allowed directly
 "glob": "allow",  // File wildcard search: allowed directly
 "grep": "allow",  // Content search: allowed directly
 "list": "allow",  // List directories: allowed directly
 "bash": {
 "*": "ask", // Bash commands default to prompting
 "git status *": "allow",  // Check git status: allowed
 "git log *": "allow", // Check git logs: allowed
 "git diff *": "allow",  // Check git diffs: allowed
 "npm run *": "allow", // Run npm scripts: allowed
 "npm test *": "allow",  // Run tests: allowed
 "rm *": "deny"  // Delete files: blocked outright
 }
 }
}

Example 3: Allow Access to Multiple Project Directories

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

Example

{
 "$schema": "https://opencode.ai/config.json",

 "permission": {
 "external_directory": {
 "~/projects/personal/**": "allow", // Allow access to personal project directory
 "~/projects/work/**": "allow", // Allow access to work project directory
 "~/dotfiles/**": "allow" // Allow access to config directory
 },
 "edit": {
 "~/dotfiles/**": "deny" // Even if allowed access to dotfiles, prohibit editing (read-only)
 }
 }
}
← Opencode McpOpencode Commands β†’