Skip to content

fix: authoritative managed-settings.json applied after all user config#22296

Open
Daviey wants to merge 8 commits intoanomalyco:devfrom
Daviey:fix/managed-settings-authoritative
Open

fix: authoritative managed-settings.json applied after all user config#22296
Daviey wants to merge 8 commits intoanomalyco:devfrom
Daviey:fix/managed-settings-authoritative

Conversation

@Daviey
Copy link
Copy Markdown

@Daviey Daviey commented Apr 13, 2026

Issue for this PR

Closes #22292

Type of change

  • Bug fix

What does this PR do?

Two bypass vectors allowed users to override enterprise managed config:

  1. OPENCODE_PERMISSION env var was merged after managed config, so it won. A managed deny rule could be overwritten to allow.
  2. Object fields like mcp, agent, provider etc. were additively merged. Users could inject extra entries alongside managed ones (e.g. adding an evil MCP server or an extra provider).

The fix introduces managed-settings.json (and a managed-settings.d/ drop-in directory) in the system config location. It is loaded last, after all user config, project config, and OPENCODE_PERMISSION, so it cannot be overridden. Object fields in that file replace rather than merge, closing the injection vector.

The existing opencode.json managed config is unchanged and still loads earlier in the chain (for non-authoritative defaults). managed-settings.json is the opt-in high enforcement layer.

How did you verify your code works?

Three commits in this PR, each with a specific purpose:

Commit 1: 5c25db2 (tests only, no fix)

11 tests fail against unpatched code. Run with:

git checkout 5c25db25b
cd packages/opencode
bun test --test-name-pattern "managed"

Output:

(fail) managed settings override user settings
(fail) managed settings override project settings
(fail) managed instructions should replace user instructions, not union
(fail) managed agents should replace user agents, not additively merge
(fail) managed mcp should replace user mcp, not additively merge
(fail) managed commands should replace user commands, not additively merge
(fail) managed providers should replace user providers, not additively merge
(fail) managed formatters should replace user formatters, not additively merge
(fail) managed lsp should replace user lsp, not additively merge
(fail) managed experimental should replace user experimental, not additively merge
(fail) managed skills should replace user skills, not additively merge

3 pass, 9 skip, 11 fail

Commit 2: c5ca9d1 (the fix)

Same tests, now all pass:

git checkout c5ca9d10c
cd packages/opencode
bun test --test-name-pattern "managed"

Output:

14 pass, 9 skip, 0 fail

The 3 tests that already passed at commit 1 (permission deny via OPENCODE_PERMISSION, drop-in fragment ordering, dotfile ignore) continue to pass.

Commit 3: 3a3c2f2 (docs)

Adds documentation for managed-settings.json and managed-settings.d/ drop-in fragments to packages/web/src/content/docs/config.mdx. No code changes.

Screenshots / recordings

N/A, no UI changes.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

Daviey added 3 commits April 13, 2026 13:26
9 tests that fail on unpatched code, proving two bypass vectors:

1. OPENCODE_PERMISSION env var overwrites managed deny rules
   (mergeDeep second-arg-wins semantics)

2. Additive object merging lets users inject entries into managed
   fields (agent, mcp, instructions, provider, formatter, lsp,
   command, experimental, skills) that survive alongside managed
   config instead of being replaced
Introduce managed-settings.json (with managed-settings.d/ drop-in
fragments) loaded after OPENCODE_PERMISSION and legacy tools,
making it the authoritative final word.

Object/array fields (agent, command, experimental, formatter,
instructions, lsp, mcp, mode, provider, skills) are replaced
entirely rather than additively merged, preventing users from
injecting entries alongside managed ones.
@Daviey Daviey changed the title Fix/managed settings authoritative fix: authoritative managed-settings.json applied after all user config Apr 13, 2026
@github-actions
Copy link
Copy Markdown
Contributor

Hey! Your PR title Fix/managed settings authoritative doesn't follow conventional commit format.

Please update it to start with one of:

  • feat: or feat(scope): new feature
  • fix: or fix(scope): bug fix
  • docs: or docs(scope): documentation changes
  • chore: or chore(scope): maintenance tasks
  • refactor: or refactor(scope): code refactoring
  • test: or test(scope): adding or updating tests

Where scope is the package name (e.g., app, desktop, opencode).

See CONTRIBUTING.md for details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Managed settings can be bypassed via OPENCODE_PERMISSION env var and additive object merging

1 participant