Permissions
The permissions system controls which tools opencode's agents can invoke and under what conditions. Every tool call is evaluated against a set of rules that determine whether it runs automatically, prompts you for approval, or is blocked entirely.
Permission Actions
Each permission rule maps a tool or command pattern to one of three actions:
| Action | Description |
|---|---|
allow | The tool runs immediately without any prompt. |
ask | The tool prompts you for approval before running. The UI offers three choices: run once, always allow, or reject. |
deny | The tool is blocked and will not execute. |
What "Ask" Looks Like
When a tool requires approval, the interface displays the tool name, its arguments, and three buttons:
- Once – Approve this single invocation.
- Always – Approve this invocation and remember the decision for the session.
- Reject – Block this invocation.
The "Always" preference is transient and resets when the session ends.
Global Permission Configuration
The simplest configuration applies a single action to every tool:
{
"permission": "allow"
}
This grants unrestricted tool access. Use with caution.
A more practical global setup uses a wildcard pattern to set a baseline and then overrides individual tools:
{
"permission": {
"*": "ask",
"bash": "allow",
"read": "allow",
"edit": "deny",
"webfetch": "allow"
}
}
The wildcard "*" applies to every tool that does not have a more specific rule. This is a safe starting point: most day-to-day tools are allowed, write operations require approval, and filesystem modifications are blocked.
Per-Tool Permission Rules
You can set rules for individual tools. Every built-in tool supports the three actions:
{
"permission": {
"read": "allow",
"grep": "allow",
"glob": "allow",
"bash": "ask",
"edit": "deny",
"write": "deny",
"task": "ask",
"webfetch": "ask",
"websearch": "ask",
"skill": "allow",
"lsp": "allow",
"question": "ask"
}
}
Granular Bash Rules with Pattern Matching
The bash tool supports fine-grained command-level patterns. Instead of a single action for all shell commands, define multiple patterns:
{
"permission": {
"bash": {
"*": "ask",
"git *": "allow",
"npm *": "allow",
"pnpm *": "allow",
"yarn *": "allow",
"cargo *": "allow",
"go *": "allow",
"ls *": "allow",
"cat *": "allow",
"ps *": "allow",
"curl *": "ask",
"rm *": "deny",
"chmod *": "deny",
"chown *": "deny",
"sudo *": "deny",
"> *": "ask",
"|* sh": "ask",
"eval *": "deny"
}
}
}
Pattern Matching Rules
Wildcard patterns follow standard glob conventions:
*matches zero or more characters.?matches exactly one character.- Patterns are matched against the full command string.
- The last matching rule wins. Order your rules from broad to specific.
Evaluation Order Example
{
"bash": {
"npm *": "allow",
"npm publish *": "ask",
"npm run *": "allow",
"npm run deploy:*": "deny"
}
}
With these rules:
npm installmatchesnpm *→ allownpm publishmatches bothnpm *andnpm publish *. Sincenpm publish *is the last match, it wins → asknpm run buildmatchesnpm *andnpm run *. Last match wins → allownpm run deploy:prodmatchesnpm *,npm run *, andnpm run deploy:*. Last match → deny
Granular Edit Rules
The edit tool supports path-based patterns so you can restrict which files the agent may modify:
{
"permission": {
"edit": {
"*": "deny",
"src/**/*.ts": "allow",
"src/**/*.tsx": "allow",
"tests/**/*.test.ts": "allow",
"packages/web/src/content/docs/*.mdx": "allow",
"*.md": "ask",
"package.json": "ask"
}
}
}
External Directory Permissions
By default, agents can only access files inside the project root. To grant access to paths outside the project, use the external_directory permission:
{
"permission": {
"external_directory": {
"*": "ask",
"~/projects/shared-lib/**": "allow",
"~/Documents/notes/**": "allow",
"/etc/nginx/sites-enabled/*": "deny"
}
}
}
Patterns beginning with ~ or $HOME expand to the user's home directory.
Available Tools
The following tools can have permission rules:
| Tool | Default | Description |
|---|---|---|
read | allow | Read file contents |
edit | allow | Edit, write, or patch files |
glob | allow | Pattern-based file search |
grep | allow | Content search within files |
bash | allow | Execute shell commands |
task | allow | Delegate work to subagents |
skill | allow | Load skill instructions |
lsp | allow | Language server protocol queries |
question | allow | Ask the user a question |
webfetch | allow | Fetch URL content |
websearch | allow | Search the web |
external_directory | ask | Access paths outside the project root |
doom_loop | ask | Detect and break infinite loops |
Security-Sensitive Defaults
The read tool denies access to .env files and similar credential stores by default. This prevents accidental exposure of secrets through tool output.
Agent-Level Permission Overrides
Agents can override global permissions in their own configuration. This lets you create specialized agents with different trust levels:
{
"agent": {
"code-reviewer": {
"description": "Reviews code without making changes",
"mode": "subagent",
"permission": {
"edit": "deny",
"write": "deny",
"bash": "ask"
}
},
"deploy-agent": {
"description": "Handles deployment pipelines",
"mode": "subagent",
"permission": {
"bash": {
"*": "deny",
"npm run build": "allow",
"npm run deploy:*": "allow"
}
}
}
}
}
Agent permissions take precedence over global permissions. If a global rule allows edit but the agent denies it, the agent wins.
Legacy Tools Configuration
Versions prior to 1.1.1 used a tools configuration block. This format is still supported for backwards compatibility:
{
"tools": {
"allow": ["bash", "read", "glob", "grep"],
"deny": ["edit"],
"ask": ["webfetch"]
}
}
When both permission and tools are present, permission takes precedence.
Best Practices
Start Restrictive
Begin with a conservative baseline and open up tools as needed:
{
"permission": {
"*": "ask",
"read": "allow",
"glob": "allow",
"grep": "allow"
}
}
Protect Destructive Commands
Always deny or ask for dangerous shell operations:
{
"bash": {
"rm -rf *": "deny",
"sudo *": "deny",
"> *": "ask",
"dd *": "deny",
"reboot": "deny",
"shutdown": "deny"
}
}
Scope Subagent Permissions
Restrict subagents that handle sensitive operations. A deployment agent should not be able to read environment files or modify source code arbitrarily.
Use Deny as a Safety Net
The deny action prevents entire categories of operations. Use it for operations that should never happen automatically, such as modifying system configuration files or deleting data.