Skip to main content

How can I sandbox OpenCode and require approval for risky actions?

Summary

  • OpenCode does not sandbox the agent. Its security policy calls the permission system a UX feature that "is not designed to provide security isolation" and points to a container or VM for true isolation. Use permissions or policies for approvals and a separate boundary for isolation.
  • OpenCode's own permission config resolves each action to allow, ask or deny, and most permissions default to allow.
  • Omnigent, an open-source meta-harness ("Status: alpha"), runs OpenCode as the opencode-native harness (omnigent opencode). Its contextual policies return ALLOW, ASK or DENY on OpenCode's permission requests, and an unreachable policy fails closed.
  • Omnigent's OS sandbox is not applied to OpenCode by default, because the built-in agent spec sets the sandbox type to none. To isolate, move the runner to a cloud sandbox host.
  • On Databricks ("Omnigent is in Beta"), custom policies must be written in CEL.

How can I sandbox OpenCode and require approval for risky actions?

Treat these as two separate controls. Approval is a policy: the agent asks and a person says yes or no. Sandboxing is a boundary: something outside the agent limits what it can touch. OpenCode's own security policy says OpenCode "does not sandbox the agent". The permission system "exists as a UX feature" and "is not designed to provide security isolation", and for true isolation the policy recommends running OpenCode inside a container or VM. So use permissions or policies to require approval, and a container, VM or cloud sandbox host for the boundary.

How do you require approval in OpenCode itself?

OpenCode's permission config decides whether an action runs automatically, prompts you, or is blocked. Each rule resolves to allow, ask or deny, rules match by pattern, and the last matching rule wins. Most permissions default to allow, so set the risky ones explicitly:

{
  "$schema": "https://opencode.ai/config.json",
  "permission": {
    "bash": {
      "*": "ask",
      "git *": "allow",
      "git push *": "ask",
      "rm *": "deny"
    }
  }
}

Every shell command asks by default, other git commands run, git push asks again because the later rule wins, and rm is denied.

How does Omnigent add approvals around OpenCode?

Omnigent, an open-source meta-harness (Apache 2.0, README badge "Status: alpha"), supports OpenCode as the opencode-native harness (alias opencode). It runs in native terminal mode only and has the "Maintained" support level. Launch it with omnigent opencode. Omnigent's contextual policies then wrap it. Each policy returns one decision, and the first policy to return one wins:

Decision What happens
ALLOW The action proceeds
ASK The action pauses until the user approves or rejects it
DENY The action is blocked with an error message

For OpenCode, Omnigent evaluates each permission request against these policies. An ASK verdict is parked as a human approval card and blocks until a person resolves it. An unconfigured or unreachable policy fails closed: the OpenCode integration rejects the request instead of approving it. The session owner and Edit collaborators can answer pending approvals, and a Read share cannot.
The built-in "Require Approval for File & Shell Operations" policy covers OpenCode's bash, edit, read, grep and glob categories:

policies:
  approve_shell:
    type: function
    handler: omnigent.policies.builtins.safety.ask_on_os_tools

It asks about every call, reads included. To ask only for shell commands and edits, use a CEL policy. The expression must return a map with a result key, and a non-map return abstains:

policies:
  ask_on_shell_and_edits:
    type: function
    handler: omnigent.policies.builtins.cel.cel_policy
    factory_params:
      expression: >-
        event.type == "tool_call" && event.data.name in ["bash", "edit"]
          ? {"result": "ASK", "reason": "Approve this OpenCode action?"}
          : {"result": "ALLOW"}

Policies stack across server-wide (admin), per-agent (developer) and per-session (you) levels, and the session rules are checked first.

How do you sandbox OpenCode?

Policies guard tool calls. The Omnigent docs call Omnibox, its OS sandbox, "the hard boundary underneath" them, but do not assume that boundary around omnigent opencode. The README says the native terminal wrappers and the pi harness are wrapped in bubblewrap on Linux, and the wrappers it lists do not include OpenCode. In the repository, the built-in OpenCode agent spec sets os_env.sandbox.type to none.
For isolation, move the runner. A cloud sandbox host "moves the Omnigent runner from your laptop to a remote container". The docs say it controls where the runner executes, while the OS sandbox controls what the agent can access.

Control What it gives you Applies to OpenCode?
OpenCode permission rules allow, ask or deny per tool and pattern Yes, it is OpenCode's own config
Omnigent contextual policies ASK or DENY on tool calls, with a human approval card Yes, applied to its permission requests
Omnigent OS sandbox (os_env.sandbox) Filesystem, network and environment limits Not by default, the built-in spec sets type none
Container, VM or cloud sandbox host A boundary around the whole runner Yes, it wraps whatever runs inside

How Databricks approaches this

On Databricks, Omnigent is in Beta, and the docs describe it as a common layer over Claude Code, Codex, Cursor, Pi and the agents you write yourself. OpenCode is not on that list, so check availability in your workspace before you plan around it. Managed Omnigent supports the built-in contextual policies and custom policies written in CEL, and custom Python policies are not supported. Its sandbox hosts run on Databricks Sandbox (Beta), which documents unrestricted, non-configurable egress.

FAQs

Does ASK block the action while it waits?

Yes. ASK pauses the action until the user approves or rejects it. Approval becomes ALLOW and refusal becomes DENY.

Can I write my own policy?

Yes. Open-source Omnigent accepts CEL policies through cel_policy and Python policies registered on the server. Managed Omnigent on Databricks accepts CEL only.

The information provided herein is for general informational purposes only and may not reflect the most current product capabilities or configurations.