Skip to content

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

Closed as not planned

Description

@Daviey

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:

  1. As admin: sudo tee /etc/opencode/opencode.json with { "permission": { "bash": { "curl *": "deny" } } }
  2. As user: OPENCODE_PERMISSION='{"bash":{"curl *":"allow"}}' opencode run "curl https://evil.example"
  3. The managed deny is overridden, ie curl executes.

Bypass 2:

  1. As admin: same managed config, add { "agent": { "build": { "permission": { "bash": { "*": "ask" } } } } }
  2. As user: add to ~/.config/opencode/opencode.json: { "agent": { "escape": { "permission": { "bash": { "*": "allow" } } } } }
  3. 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

Activity

  1. added
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    on Apr 13, 2026
  2. ViktorWelbers commented on Apr 17, 2026

    @ViktorWelbers

    I have implemented this in our local mirror in a similiar way - adding a way to compile opencode locally with a management setting would be great, just so you can enforce it for an organization without having settings that are easily bypassed.

  3. Daviey commented on Apr 17, 2026

    @Daviey
    Author

    @ViktorWelbers Thanks for sharing, I am curious how your implementation differs?

  4. ViktorWelbers commented on Apr 17, 2026

    @ViktorWelbers

    Honestly, I went a different way because I didn't want to fork the repo.
    My approach was using Golang and go embedd ("binary in a binary") and also embedding a json file, which are then used to manipulate the env vars (OPENCODE_PERMISSION + OPENCODE_CONFIG_CONTENT). We then just distributed the go binary as a replacement for OpenCode. When people call our custom binary those things are then set.

    For now - that's easier to maintain, since we just always fetch the latest OpenCode release and then wrap it in our binary. Works great so far. If that is of any interest, then i can post a repo somewhere.

  5. Daviey commented on Apr 21, 2026

    @Daviey
    Author

    @rekram1-node Hi, could i respectfully ask for some eyes on this bug and PR please? Thanks

  6. ViktorWelbers commented on Apr 22, 2026

    @ViktorWelbers

    @Daviey If you want, I can share our Go-Wrapper Code with you, maybe it helps. It's just 100 LoC and works both on windows, linux (and mac probably aswell, didn't test there)
    We ship that binary to our users for "safe" use of OpenCode in an Enterprise context.

  7. Daviey commented on Apr 22, 2026

    @Daviey
    Author

    @ViktorWelbers sure, I'd love to see how you are solving this. Please do share 🤩

  8. ViktorWelbers commented on Apr 27, 2026

    @ViktorWelbers

    I hope this can help, you can obv rename the wrapper, it's called opencode-guard after compilation, but renaming it to anything else should be easy.

    The make command all does the work -> loads release, and then packages binary in binary :D
    https://github.com/ViktorWelbers/opencode-enterprise-wrapper

    I have attached an example config for commands which would be restricted to only using copilot as a provider here
    https://github.com/ViktorWelbers/opencode-enterprise-wrapper/blob/main/config/opencode.json

    Adjust to your liking.

  9. removed
    bugSomething isn't working
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    on May 3, 2026
  10. markoj3s commented on May 23, 2026

    @markoj3s

    @thdxr I just saw that the bug label has been removed, but I believe current implementation is violating this precedent order claim (i.e. Managed settings override everything.), no?
    Just saying as I believe this should be prioritized.

  11. Daviey commented on May 23, 2026

    @Daviey
    Author

    @thdxr I just saw that the bug label has been removed, but I believe current implementation is violating this precedent order claim (i.e. Managed settings override everything.), no? Just saying as I believe this should be prioritized.

    Exactly this, If you see my comment on the PR:

    @rekram1-node Please can this get your attention?
    
    Just to note, the current published documentation states "Managed settings override everything." and "Organizations can enforce configuration that users cannot override. Managed settings are loaded at the highest priority tier."
    
    Which as it currently stands is entirely inaccurate.  Please can you consider merging this PR.
    
    Thanks
    
  12. markoj3s commented on May 24, 2026

    @markoj3s

    Fully agree..!

  13. github-actions commented on Jul 24, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions