agentsclimarketplace

Opencode permissions

Skill Timmy6942025/opencode-builder-skill/skills/opencode-permissions

Kilo/agent skill for building OpenCode extensions, plugins, and integrations

Install
npx -y skills add Timmy6942025/opencode-builder-skill --skill opencode-permissions

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Use this skill when configuring OpenCode's permission system β€” controlling which tools require approval, setting granular bash command rules, managing external directory access, configuring per-agent permissions, or understanding the allow/ask/deny permission model. Covers wildcards, pattern matching, doom loop detection, and the complete permission key reference.

SKILL.md

11.2 KB, as published. Nobody here has run it

OpenCode Permissions

πŸ“š Official Docs: For the latest information, always refer to the official documentation: https://opencode.ai/docs/permissions/

Control which actions require approval to run in OpenCode.

OpenCode uses the permission config to decide whether a given action should run automatically, prompt you, or be blocked. Permissions control what tools can do during a session.


Actions

Each permission rule resolves to one of three actions:

ActionBehavior
"allow"Run without approval
"ask"Prompt for approval before running
"deny"Block the action entirely

Configuration

Set All Permissions at Once

You can set a global default for all permissions:

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

Set Per-Tool Permissions

Override specific tools while keeping a global default:

{
  "$schema": "https://opencode.ai/config.json",
  "permission": {
    "*": "ask",
    "bash": "allow",
    "edit": "deny"
  }
}

Granular Rules (Object Syntax)

For most permissions, you can use an object to apply different actions based on the tool input. Rules are evaluated by pattern match, with the last matching rule winning.

Basic Pattern

{
  "$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"
    }
  }
}

In this example:

  • git status β†’ last matching rule is "git *": "allow" β†’ allowed
  • rm -rf / β†’ last matching rule is "rm *": "deny" β†’ denied
  • npm install β†’ last matching rule is "npm *": "allow" β†’ allowed
  • Edit to .mdx files β†’ allowed; edit to other files β†’ denied

Wildcards

Permission patterns use simple wildcard matching:

PatternMatches
*Zero or more of any character
?Exactly one character
All other charactersMatch literally

Examples:

  • "git *" matches git status, git commit -m "msg", git push origin main
  • "git ?*" matches git status but not git alone
  • "rm *" matches rm file.txt, rm -rf /tmp/dir

Home Directory Expansion

You can use ~ or $HOME at the start of a pattern to reference your home directory:

PatternExpands To
~/projects/*/Users/username/projects/*
$HOME/projects/*/Users/username/projects/*
~/Users/username

This is particularly useful for external_directory rules.


Available Permissions

OpenCode permissions are keyed by tool name, plus a couple of safety guards:

KeyTools It GatesMatching Input
readreadFile path
editwrite, edit, apply_patchFile path
globglobGlob pattern
grepgrepRegex pattern
bashbashParsed command (e.g., git status --porcelain)
tasktaskSubagent type
skillskillSkill name
lsplsp(non-granular currently)
questionquestion(non-granular)
webfetchwebfetchURL
websearchwebsearchQuery
external_directoryAny tool reading/writing outside projectPath
todowritetodowrite, todoread(non-granular)
doom_loopRecovery when same tool call repeats 3x with identical input(non-granular)

The read, edit, glob, grep, list, bash, task, external_directory, lsp, and skill keys accept either a shorthand action ("allow" | "ask" | "deny") or an object of glob/pattern β†’ action for fine-grained control. The remaining keys accept the shorthand action only.


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:
{
  "permission": {
    "read": {
      "*": "allow",
      "*.env": "deny",
      "*.env.*": "deny",
      "*.env.example": "allow"
    }
  }
}

What "Ask" Does

When OpenCode prompts for approval, the UI offers three outcomes:

OutcomeBehavior
onceApprove just this request
alwaysApprove future requests matching the suggested patterns (for the rest of the current OpenCode session)
rejectDeny 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*).


External Directories

Use external_directory to allow tool calls that touch paths outside the working directory where OpenCode was started. This applies to any tool that takes a path as input (e.g., read, edit, glob, grep, and many bash commands).

Home expansion (~/...) only affects how a pattern is written. It does not make an external path part of the current workspace, so paths outside the working directory must still be allowed via external_directory.

Allow Access to a Directory

{
  "$schema": "https://opencode.ai/config.json",
  "permission": {
    "external_directory": {
      "~/projects/personal/**": "allow"
    }
  }
}

Layer Additional Rules

Any directory allowed here inherits the same defaults as the current workspace. Since read defaults to allow, reads are also allowed for entries under external_directory unless overridden:

{
  "$schema": "https://opencode.ai/config.json",
  "permission": {
    "external_directory": {
      "~/projects/personal/**": "allow"
    },
    "edit": {
      "~/projects/personal/**": "deny"
    }
  }
}

This allows reading files in ~/projects/personal/ but blocks editing them.


Agent Permissions

You can override permissions per agent. Agent permissions are merged with the global config, and agent rules take precedence.

JSON Configuration

{
  "$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"
        }
      }
    }
  }
}

Markdown Agent Configuration

---
description: Code review without edits
mode: subagent
permission:
  edit: deny
  bash: ask
  webfetch: deny
---
Only analyze code and suggest changes.

Bash Permission Patterns

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.

{
  "permission": {
    "bash": {
      "*": "ask",
      "git status *": "allow",
      "git diff *": "allow",
      "git log *": "allow",
      "npm test *": "allow",
      "npm run *": "allow",
      "rm *": "deny"
    }
  }
}

Complete Examples

Restrictive Setup

Everything requires approval except safe read operations:

{
  "$schema": "https://opencode.ai/config.json",
  "permission": {
    "*": "ask",
    "read": "allow",
    "glob": "allow",
    "grep": "allow",
    "skill": "allow",
    "question": "allow"
  }
}

Permissive with Specific Denials

Allow everything except dangerous operations:

{
  "$schema": "https://opencode.ai/config.json",
  "permission": {
    "*": "allow",
    "bash": {
      "*": "allow",
      "rm -rf *": "deny",
      "sudo *": "deny",
      "git push --force *": "deny"
    },
    "external_directory": "ask"
  }
}

Development Agent with Git Restrictions

{
  "agent": {
    "build": {
      "permission": {
        "bash": {
          "*": "allow",
          "git push *": "ask",
          "git commit *": "ask",
          "rm *": "ask"
        },
        "edit": {
          "*.env": "deny",
          "*.env.*": "deny",
          "*": "allow"
        }
      }
    }
  }
}

Read-Only Review Agent

{
  "agent": {
    "reviewer": {
      "mode": "subagent",
      "permission": {
        "edit": "deny",
        "bash": {
          "*": "deny",
          "git diff *": "allow",
          "git log *": "allow",
          "grep *": "allow",
          "find *": "allow"
        },
        "webfetch": "allow",
        "skill": "allow"
      }
    }
  }
}

MCP Tool Permissions

You can control permissions for MCP server tools using glob patterns on the tool name prefix:

{
  "$schema": "https://opencode.ai/config.json",
  "permission": {
    "sentry_*": "allow",
    "context7_*": "ask",
    "github_*": {
      "*": "ask",
      "github_list_repos *": "allow",
      "github_create_issue *": "deny"
    }
  }
}

Doom Loop Detection

The doom_loop permission triggers when the same tool call repeats 3 times with identical input. This is a safety mechanism to prevent infinite loops. It defaults to "ask", giving you the option to break out of the loop.

{
  "$schema": "https://opencode.ai/config.json",
  "permission": {
    "doom_loop": "deny"
  }
}

Troubleshooting

Tool Blocked Unexpectedly

  1. Check the global permission config in opencode.json
  2. Check agent-specific permissions (agent rules take precedence)
  3. Check if the tool matches a deny pattern
  4. Use opencode debug config to see the resolved permission config

Permission Prompts Too Frequent

  1. Use the always option in the permission dialog to whitelist patterns
  2. Configure explicit "allow" rules for safe commands
  3. Use object syntax to allow specific command patterns

.env Files Blocked

This is the default behavior. The read permission denies *.env and *.env.* by default. Override with:

{
  "permission": {
    "read": {
      "*": "allow",
      "*.env": "allow"
    }
  }
}

Warning: Allowing .env reads means the LLM can see your secrets. Only do this if you understand the security implications.


Key Points

  1. Last match wins β€” Put broad rules first, specific exceptions after
  2. Agent overrides global β€” Agent-specific permissions take precedence
  3. .env denied by default β€” Override explicitly if needed
  4. external_directory and doom_loop default to "ask" β€” Everything else defaults to "allow"
  5. Patterns use simple globs β€” * matches anything, ? matches one character
  6. always in the UI β€” Whitelists patterns for the rest of the session
  7. MCP tools use prefix matching β€” servername_* matches all tools from that server

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.