Description
Follow-up to #6358 and #19158. Managed settings (/etc/opencode/opencode.json etc.) are intended to let admins enforce config that users cannot override. Two gaps break this guarantee:
1. OPENCODE_PERMISSION env var overwrites managed permission rules.
In config.ts, managed config is applied at step 8 but OPENCODE_PERMISSION is applied at step 11 as mergeDeep(result.permission, JSON.parse(OPENCODE_PERMISSION)). Since the env var is the second argument, it wins a user can restore any managed deny rule to allow by setting this env var.
2. Object fields are merged additively, not replaced.
Fields like mcp, agent, instructions, provider, formatter, lsp, command, mode, skills, and experimental are deep-merged with user config rather than replaced. A user can inject entries (e.g. an escape agent with bash: allow) alongside managed ones. The admin cannot lock down these fields.
Plugins
None
OpenCode version
1.4.3 (dev branch, cb1a500)
Steps to reproduce
Bypass 1:
- As admin:
sudo tee /etc/opencode/opencode.json with { "permission": { "bash": { "curl *": "deny" } } }
- As user:
OPENCODE_PERMISSION='{"bash":{"curl *":"allow"}}' opencode run "curl https://evil.example"
- The managed deny is overridden, ie curl executes.
Bypass 2:
- As admin: same managed config, add
{ "agent": { "build": { "permission": { "bash": { "*": "ask" } } } } }
- As user: add to
~/.config/opencode/opencode.json: { "agent": { "escape": { "permission": { "bash": { "*": "allow" } } } } }
- The
escape agent survives alongside the managed build agent and can be selected to bypass restrictions.
Screenshot and/or share link
No response
Operating System
All platforms (Linux, macOS, Windows)
Terminal
Any
Description
Follow-up to #6358 and #19158. Managed settings (
/etc/opencode/opencode.jsonetc.) are intended to let admins enforce config that users cannot override. Two gaps break this guarantee:1.
OPENCODE_PERMISSIONenv var overwrites managedpermissionrules.In
config.ts, managed config is applied at step 8 butOPENCODE_PERMISSIONis applied at step 11 asmergeDeep(result.permission, JSON.parse(OPENCODE_PERMISSION)). Since the env var is the second argument, it wins a user can restore any managed deny rule toallowby setting this env var.2. Object fields are merged additively, not replaced.
Fields like
mcp,agent,instructions,provider,formatter,lsp,command,mode,skills, andexperimentalare deep-merged with user config rather than replaced. A user can inject entries (e.g. anescapeagent withbash: allow) alongside managed ones. The admin cannot lock down these fields.Plugins
None
OpenCode version
1.4.3 (dev branch, cb1a500)
Steps to reproduce
Bypass 1:
sudo tee /etc/opencode/opencode.jsonwith{ "permission": { "bash": { "curl *": "deny" } } }OPENCODE_PERMISSION='{"bash":{"curl *":"allow"}}' opencode run "curl https://evil.example"Bypass 2:
{ "agent": { "build": { "permission": { "bash": { "*": "ask" } } } } }~/.config/opencode/opencode.json:{ "agent": { "escape": { "permission": { "bash": { "*": "allow" } } } } }escapeagent survives alongside the managedbuildagent and can be selected to bypass restrictions.Screenshot and/or share link
No response
Operating System
All platforms (Linux, macOS, Windows)
Terminal
Any