# Opencode Permission

> Manage OpenCode's permission rules in opencode.jsonc — add, remove, or list auto-approval rules for Bash commands and tool invocations so the agent stops asking for confirmation on every single command. Use whenever the user wants to auto-approve, deny, or require confirmation for a shell command, even if they don't mention "permission" or "opencode.jsonc" directly. Triggers on "允许 kubectl get *", "拒绝 rm -rf", "auto-approve npm run build", "总是执行 git status", "add permission rule", "list my permissions", "查看权限", "添加权限", "移除权限", "把 X 加到允许列表", "skip confirmation for", and similar — even if the user doesn't explicitly mention OpenCode's config.

- Skill: `cnife/opencode-permission` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add cnife/opencode-permission`
- Raw SKILL.md: https://api.skillmd.com/api/skills/cnife/opencode-permission/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: cnife (https://skillmd.com/u/cnife)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/cnife/opencode-permission

---


# OpenCode Permission Manager

Manage `permission` rules in `~/.config/opencode/opencode.jsonc`. Add, remove, list, or format auto-approval rules for shell commands and tool invocations.

## Workflow

1. Identify the rule string(s) and action from the user's request (e.g., `"kubectl get *"` → `allow`)
2. Determine the subcommand: `add` / `remove` / `list` / `list-all` / `format`
3. Run the bundled script:

   ```bash
   # 单条添加
   uv run --script <skill-path>/scripts/manage_permission.py add "kubectl get *" --action allow

   # 批量添加
   uv run --script <skill-path>/scripts/manage_permission.py add "kubectl get *" "kubectl describe *" "kubectl logs *"
   ```

4. Confirm the change was written
5. Remind the user: **修改配置后需要重启 OpenCode 才能生效**

## Behaviors

- **自动备份**：`add` / `remove` / `format` 操作会在写入前创建带时间戳的备份，文件名格式 `opencode.jsonc.YYYYMMDDTHHMMSS.bak`，多次变更各自保留。
- **自动格式化**：`add` / `remove` 操作完成后自动规范 bash 段格式，保证每条规则独占一行。
- **批量添加**：`add` 接受多个位置参数，只需一次执行。

## Command Reference

### Add rules

```bash
# 单条（默认 action=allow）
uv run --script manage_permission.py add "kubectl get *"

# 批量添加
uv run --script manage_permission.py add "kubectl get *" "kubectl describe *" "kubectl logs *"

# 指定 action
uv run --script manage_permission.py add "git commit *" --action ask
uv run --script manage_permission.py add "rm -rf *" --action deny

# 自定义配置路径
uv run --script manage_permission.py add "kubectl get *" --config /path/to/opencode.jsonc
```

### Remove a rule

```bash
uv run --script manage_permission.py remove "kubectl get *"
```

### List rules

```bash
# List permission.bash only
uv run --script manage_permission.py list

# List all permission categories (bash, read, edit, etc.)
uv run --script manage_permission.py list-all
```

### Format rules

```bash
# 格式化 bash 规则（一行一条，自动备份）
uv run --script manage_permission.py format
```

## Rule Format Reference

### Permission actions

| Value | Meaning |
|-------|---------|
| `allow` | Auto-execute, no confirmation needed |
| `ask` | Prompt for confirmation each time |
| `deny` | Block the command entirely |

### Wildcard syntax

| Symbol | Meaning | Example |
|--------|---------|---------|
| `*` | Matches zero or more characters | `"git *"` matches `git status`, `git diff --staged` |
| `?` | Matches exactly one character | `"ls ?"` matches `ls -l` but not `ls -la` |

**Important**: `"git status"` only matches `git status` with no arguments. To match with arguments, use `"git status *"`.

### Available permission keys

| Key | Matches | Description |
|-----|---------|-------------|
| `bash` | Shell command pattern | Command execution (e.g., `"kubectl get *"`) |
| `read` | File path | File reading operations |
| `edit` | File path | File modifications (edit/write/patch) |
| `glob` | Glob pattern | File wildcard search |
| `grep` | Regex pattern | Content search |
| `list` | Directory path | Directory listing |
| `task` | Subagent type | Subagent spawning |
| `lsp` | LSP query | Language server queries |
| `skill` | Skill name | Skill loading |
| `external_directory` | File path | Access outside working directory |
| `todowrite` | — | Todo writing (simple, no pattern matching) |
| `question` | — | Asking user questions (simple) |
| `webfetch` | URL | Web fetching (simple) |
| `websearch` / `codesearch` | Search query | Web/code search (simple) |
| `doom_loop` | — | Repeated tool call detection (simple) |

Simple keys (no pattern matching) accept only `"allow"`, `"ask"`, or `"deny"` as a string value.

### Rule matching logic

- **Last matching rule wins** — more specific rules override `"*"` defaults
- Common pattern: set `"*": "ask"` as fallback, then add specific `allow` rules
- Supports `~` and `$HOME` path expansion for file-related keys

### Configuration file format

- **Location**: `~/.config/opencode/opencode.jsonc` (global) or `<project>/.opencode/opencode.jsonc` (project-level)
- **Format**: JSONC (JSON with Comments) — supports `//` and `/* */` comments
- **Structure**:

  ```jsonc
  {
    "permission": {
      "edit": "ask",
      "bash": {
        "*": "ask",
        "kubectl get *": "allow",
        "git status *": "allow"
      }
    }
  }
  ```

- **Agent-level override**: Rules can also be set per-agent in the `agent` section, which take precedence over global rules

## Examples

### Allow all kubectl read operations

```bash
uv run --script manage_permission.py add \
  "kubectl get *" \
  "kubectl describe *" \
  "kubectl logs *" \
  "kubectl top *" \
  "kubectl explain *" \
  "kubectl diff *" \
  "kubectl auth can-i *"
```

### Allow git commit but require confirmation for push

```bash
uv run --script manage_permission.py add "git commit *" --action allow
uv run --script manage_permission.py add "git push *" --action ask
```

### Block dangerous commands

```bash
uv run --script manage_permission.py add "rm -rf *" --action deny
```

### Format existing config

```bash
uv run --script manage_permission.py format
```

### View current rules

```bash
uv run --script manage_permission.py list
```

## Notes

- Uses `json-five` (ModelLoader/ModelDumper) to preserve all existing comments during read-modify-write cycles.
- New rules are appended to the end of `permission.bash`; after writing, the bash section is automatically formatted to one-rule-per-line.
- `add` / `remove` / `format` create a timestamped backup before writing (e.g., `opencode.jsonc.20260428T153045.bak`).

