anomalyco / anomalyco/opencode
[FEATURE]: Replace order-dependent (first-match) permission evaluation with set-based inheritance (specifcity and precedence)
@kitlangton is already working on this.
Since Aug 6, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Feature hasn't been suggested before.
- I have verified this feature I'm about to request hasn't been suggested before.
Describe the enhancement you want to request
OpenCode’s permission engine evaluates bash permissions using a sequential "last-match-wins" evaluation model driven by dictionary merging and rule array iteration.
While simple to implement, this approach creates severe operational friction, maintenance bloat, and safety risks when managing non-trivial CLI permissions across multiple sub-agents:
-
No Grouping or Macro Capabilities: Security policies require explicitly listing every command, sub-command, and flag variation (e.g., repeating dozens of
git,docker,npm, andrtkvariations across every agent file). -
Fragile Rule Ordering: Evaluation relies strictly on document or dictionary insertion order rather than pattern specificity. Accidentally moving a catch-all pattern (
git*or*) below a specific override (such asgit checkout -- *) silently invalidates the finer-grained restriction. -
Ambiguous Inheritance Semantics: Agent inheritance via
extendsperforms a shallow dictionary merge where child rules append after parent rules. Because there is no formal concept of additive delegation versus subtractive boundary enforcement, child agents overwrite parent keys based purely on position. This makes it impossible to predictably build either strict Default-Allow / Subtractive (Boundary) or Default-Deny / Additive (Capability) security topologies.
Security Risk: Host Execution Without Sandboxing
OpenCode agents execute bash commands directly on the host operating system without container isolation or OS-level sandboxing by default.
In an unsandboxed host environment, permission configuration errors carry severe consequences:
-
Unintended data loss (e.g., recursive directory deletion
rm -rf *, uncommitted state discards viagit checkout .*). -
Non-self-contained system alterations (e.g., package manager modifications via
apt,pip install,systemctlmodifications, or privilege escalation viasudo). -
Exfiltration or unexpected network side-effects via
curlorssh.
A permission engine that relies on fragile array ordering and ambiguous inheritance mechanics increases the risk of accidental host compromise.
Real-World Access Control Paradigms
Established access control systems handle permissions using explicit, deterministic evaluation rules rather than document ordering:
-
AWS IAM (Identity and Access Management): Uses Permissions Boundaries (Service Control Policies) for subtractive restriction alongside Identity Policies for additive capabilities. An explicit
Denyin a boundary hard-caps child elevation. -
Kubernetes RBAC: Additive / Least Privilege Model: Operations start denied by default. Roles grant specific capabilities (
verbsonresources). Child/bound roles additively expand access without order-dependent array bugs. -
Linux Security Modules (AppArmor / SELinux): Subtractive Confinement: Profiles strictly limit capabilities. Specific path rules automatically take precedence over broad wildcards regardless of line order in the profile file.
-
Network Firewalls & Policy Engines (Open Policy Agent / Rego): Evaluate ASTs where rule matching prioritizes Pattern Specificity over declaration sequence.
Proposed Solution
Redesign OpenCode's permission engine around a deterministic, multi-tiered resolution model that supports both additive and subtractive configuration styles.
1. Command Grouping (Macros / Aliases)
Allow defining reusable command arrays in the root opencode.json so agents can reference whole categories of actions rather than maintaining exhaustive flag lists.
2. Pattern Specificity Engine (Glob Trie / AST)
Eliminate line-order sensitivity. When a command is executed, match all applicable globs and resolve conflicts using pattern specificity. Exact subcommands (git branch --delete*) take precedence over broader subcommands (git branch*), which take precedence over global wildcards (git* or *).
3. Clear Rule Resolution Hierarchy
Resolve overlapping permission decisions using a deterministic 3-step evaluation order:
- Specificity First: The rule matching the most specific glob pattern always wins (e.g.,
rm -rf /beats@destructive-git-safeor*). - Locality / Inheritance Scope: When glob patterns are identical in specificity, the most local rule wins (e.g., a child agent's rule for
rm *overrides an inherited parent or global rule forrm *). - Configurable Verb Precedence (Fallback): When rules conflict at the exact same specificity and scope level, apply the policy's resolution strategy (e.g.,
Deny>Ask>Allowinstrictmode, orAllow>Ask>Denyinpermissivemode).
4. Explicit Inheritance Modes (mode: additive vs mode: subtractive)
To remove ambiguity, formalize permission inheritance in child agents using an explicit mode directive:
-
mode: additive(Capability Grants / Default-Deny):- The parent establishes the baseline bounds.
- The child uses
mode: additiveto widen access (e.g., elevating@destructive-git-safefromask$\rightarrow$allow).
-
mode: subtractive(Guardrails / Default-Allow):- The parent provides broad access.
- The child uses
mode: subtractiveto narrow access (e.g., downgrading@destructivefromallow$\rightarrow$deny).
-
Enforceable Boundaries (
sealedrules):- Rules declared in
opencode.jsonor parent agents usingsealed: true(or aseal:block) create a permission ceiling/floor that child agents cannot override, regardless of inheritance mode or local specificity.
- Rules declared in
Proposed Configuration Examples
Root Configuration (opencode.jsonc)
Define macro groups, baseline defaults, and un-overrideable hard boundaries:
{
"$schema": "https://opencode.ai/config.json",
"permission": {
// Reusable command groups
"groups": {
"@read-only": [
"rtk git status*", "rtk git log*", "rtk git diff*", "rtk ls*", "rtk rg*", "pwd"
],
"@mutation": [
"bun build*", "bun install*", "rtk cargo build*", "mkdir *", "touch *"
],
"@destructive-git-safe": [
"cp *", "rtk git add*", "git rm*", "mv *", "rm *"
],
"@destructive": [
"apt *", "sudo *", "rtk git checkout -- *", "git clean*", "rm -rf *"
]
},
"bash": {
"default": "deny",
// Universal baseline permissions
"rules": {
"@read-only": "allow",
"@mutation": "deny",
"@destructive-git-safe": "deny",
"@destructive": "deny"
},
// Sealed boundaries that no agent or sub-agent can override
"seal": {
"sudo *": "deny",
"rm -rf /": "deny"
}
}
}
}
Additive Inheritance Example: Building Capabilities Top-Down
In an additive setup, the base agent starts restricted, and child agents selectively elevate capabilities.
Base Agent (.opencode/agents/adhoc.yaml)
name: adhoc
description: Ad-hoc runner with intermediate interactive capabilities
mode: subagent
permission:
bash:
mode: additive # Explicitly state that rules in this block elevate privileges
rules:
"@mutation": allow
"@destructive-git-safe": ask
"@destructive": ask
Child Agent (.opencode/agents/coder.yaml)
coder extends adhoc. Because it specifies mode: additive, it additively expands git-safe operations from ask to allow, while specific pattern overrides (git push --force*) protect critical workflows regardless of declaration order.
name: coder
description: Primary development agent
mode: subagent
extends: adhoc
permission:
bash:
mode: additive # Widens permissions inherited from 'adhoc'
rules:
# Capability Elevation: Elevates '@destructive-git-safe' from 'ask' -> 'allow'
"@destructive-git-safe": allow
# Specific glob override (Specificity Engine ensures this beats '@destructive-git-safe')
"git push --force*": ask
Subtractive Inheritance Example: Applying Guardrails Bottom-Up
In a subtractive setup, a parent agent starts with broad permissions, and specialized sub-agents narrow the blast radius.
Base Autonomous Agent (.opencode/agents/power-user.yaml)
name: power-user
description: High-privilege agent for automated environment setup
mode: subagent
permission:
bash:
mode: additive
rules:
"@mutation": allow
"@destructive-git-safe": allow
"@destructive": allow
Specialized Restricted Child (.opencode/agents/reviewer.yaml)
reviewer inherits broad power from power-user, but uses mode: subtractive to enforce narrow security guardrails for safe code review.
name: reviewer
description: Code review sub-agent constrained to safe operations
mode: subagent
extends: power-user
permission:
bash:
mode: subtractive # Narrows/restricts permissions inherited from 'power-user'
rules:
# Restricts mutations to interactive prompts
"@mutation": ask
# Hard-denies destructive actions regardless of parent 'allow'
"@destructive-git-safe": deny
"@destructive": deny
Expected Impact
- Determinism: Eliminates hidden bugs caused by TOML key sorting or JSON rule array placement.
- Flexibility: Cleanly supports both Default-Deny additive capability workflows and Default-Allow subtractive boundary workflows via explicit
modedeclarations. - Maintainability: Reduces agent frontmatter definitions by 80–90% through reusable command groups.
- Host Safety: Guarantees that explicit system safety rules (e.g.,
sudo *,rm -rf /) sealed at the global layer cannot be accidentally bypassed by sub-agent extensions.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.