feat: align permission defaults with Claude Code#30
Conversation
Reduce excessive approval prompts by expanding OpenCode's permission config to mirror Claude Code's ergonomic defaults: auto-allow for read/edit/glob/grep/web tools, pattern-based bash whitelist for common dev commands, and explicit deny rules for dangerous operations. Closes #28 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
This PR doesn't fully meet our contributing guidelines and PR template. What needs to be fixed:
Please edit this PR description to address the above within 2 hours, or it will be automatically closed. If you believe this was flagged incorrectly, please let a maintainer know. |
There was a problem hiding this comment.
Pull request overview
Updates the repository’s checked-in OpenCode configuration to reduce permission prompts by expanding .opencode/opencode.jsonc with a Claude Code–style allow/deny ruleset (broad allows for common tools, explicit denies for sensitive operations/files).
Changes:
- Expands
permission.read/permission.editdefaults to allow-by-default with deny exceptions. - Adds a pattern-based
permission.bashwhitelist for common dev commands plus targeted deny rules. - Sets several non-file tools (glob/grep/list/websearch/webfetch/codesearch/lsp/task/skill) to
"allow", while keepingexternal_directoryat"ask".
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "cat *": "allow", | ||
| "head *": "allow", | ||
| "tail *": "allow", |
There was a problem hiding this comment.
The PR description/test plan says .env access should be denied, but the bash whitelist includes cat * (and other file-reading tools). That allows cat .env without prompting/denial, bypassing the read/edit deny rules. If the intent is to block .env/secrets access, consider removing cat from the allow-list (leave it as ask) and/or adding explicit bash deny patterns for .env*/**/.env* and **/secrets/** (plus similar read utilities like head/tail).
| "cat *": "allow", | |
| "head *": "allow", | |
| "tail *": "allow", | |
| // File-reading commands must not bypass sensitive-file deny rules | |
| "cat .env": "deny", | |
| "cat .env.*": "deny", | |
| "cat **/.env": "deny", | |
| "cat **/.env.*": "deny", | |
| "cat secrets/**": "deny", | |
| "cat **/secrets/**": "deny", | |
| "head .env": "deny", | |
| "head .env.*": "deny", | |
| "head **/.env": "deny", | |
| "head **/.env.*": "deny", | |
| "head secrets/**": "deny", | |
| "head **/secrets/**": "deny", | |
| "tail .env": "deny", | |
| "tail .env.*": "deny", | |
| "tail **/.env": "deny", | |
| "tail **/.env.*": "deny", | |
| "tail secrets/**": "deny", | |
| "tail **/secrets/**": "deny", | |
| "cat *": "ask", | |
| "head *": "ask", | |
| "tail *": "ask", |
| // Dangerous operations: deny (Claude Code denies: rm -rf, sudo, force-push) | ||
| "rm -rf *": "deny", | ||
| "sudo *": "deny", | ||
| "git push --force*": "deny", |
There was a problem hiding this comment.
git push --force* won't match common force-push forms like git push origin main --force or git push --force-with-lease because the pattern requires --force immediately after git push. Since git * is allowed above, those commands would be allowed. Consider adding deny patterns such as git push * --force* (and potentially git push * --force-with-lease*) to reliably block force pushes.
| "git push --force*": "deny", | |
| "git push --force*": "deny", | |
| "git push * --force*": "deny", | |
| "git push * --force-with-lease*": "deny", |
| // Edit operations: allow by default (Claude Code's acceptEdits mode) | ||
| // Deny migration files and sensitive configs | ||
| "edit": { | ||
| "*": "allow", | ||
| "packages/opencode/migration/*": "deny", | ||
| ".env": "deny", | ||
| ".env.*": "deny", | ||
| "**/.env": "deny", | ||
| "**/.env.*": "deny", | ||
| }, |
There was a problem hiding this comment.
The PR description says it adds .env/secrets deny rules for both read and edit, but edit only denies .env* patterns and does not deny secrets/** (or **/secrets/**). Either add the secrets deny patterns under edit as well, or update the PR description to match the actual behavior.
| "read": { | ||
| "*": "allow", | ||
| ".env": "deny", | ||
| ".env.*": "deny", | ||
| "**/.env": "deny", | ||
| "**/.env.*": "deny", | ||
| "secrets/**": "deny", | ||
| "**/secrets/**": "deny", |
There was a problem hiding this comment.
In read, patterns like .env and .env.* are unlikely to match because the Read tool checks permissions against an absolute file path (e.g. /repo/.env). The **/.env* entries will work, but the non-globbed variants are effectively dead rules and can be misleading. Consider using patterns like *.env / *.env.* (as in the guardrails configs) or dropping the redundant entries to keep the rule set clear.
Add turbo, bunx, npx, yarn, tsc, eslint, prettier, biome, jest, vitest, playwright, and common Unix utilities. Also add git push -f deny pattern to complement --force variant. Ref #28 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Claude Code allows these tool operations unconditionally. Adding them reduces unnecessary approval prompts for AI-initiated questions and todo management. Ref #28 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
.opencode/opencode.jsoncpermission config to mirror Claude Code'sacceptEdits+ allow-list modelMotivation
OpenCode's default permission config only specifies one deny rule (
packages/opencode/migration/*), causing all other tool operations to fall through to"ask". This results in significantly more approval prompts compared to Claude Code, which has a broad allow-list andacceptEditsmode.Closes #28
Test plan
🤖 Generated with Claude Code