You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Is there a way to restrict terminal command from a agent to access/edit file outside the current directory ?
I see that gemini-cli or codex-cli use seatbelt on macOS.
I don't see any equivalent for copencode.
Thanks,
Reacted by Leandro Lucarella, Draget, Charlie Knudsen, dbarbot, scarf, Léo Pradel, Matt, Julien Cornebise, Dorian Karter, Falko and 74 more
This issue might be a duplicate of existing issues. Please check:
[FEATURE] add exec tool as more secure alternative to bash tool #2206: This is a comprehensive feature request for adding sandboxing capabilities to OpenCode, addressing the same core concern about restricting agent access to files and system commands outside the current directory. It discusses security risks with the current bash tool and proposes solutions including sandboxing mechanisms similar to what you're asking about.
Feel free to ignore if none of these address your specific case.
Reacted by Luis López, Matt, Julien Cornebise, Dorian Karter, univerz, Louis Choi, Tharun T, Nicolas K., Mac Moneysac and Mohamed Abbas Mohamed Elsayed
Reacted by Andy Gimblett, Martin Häcker, Thomas Jahoda and eveeifyeve
I currently mitigate this by running opencode inside a docker container, with bind mounts of just the folders I want it to access (or which it needs); can also restrict network activity too if desired this way. Its a bit fiddly and of course container escape is possible, but better than nothing.
Reacted by Robert Sternberg, Pablo Hörtner, Chusa, Ivan Gonzalez, Gustavo Castilião, Ambi, Scott Williams, i-Nautilus and Mohamed Abbas Mohamed Elsayed
Docker containers are a good start, but when coding on Mac, you loose native tools, and docker (by itself) does not sandbox network requests, which means secret exfiltration is not mitigated at all. I very much second the attention to the anthropics sandbox-runtime.
I started off with docker as well, but as mentioned there's a lot of obstacles, incl. the auto-copy on selection in OpenCode being a big problem.
I've spent some time on the macOs sandbox-exec, which is the underlying tool anthropic's srt is using. The issue I had with srt is that I would need to build a deny list for reading permissions instead of an allowlist, and therefore used the macOs tool straight away.
Thanks for sharing! For those here not using macos and ready to test this (had no time to do so yet), here is what the bot says:
To create a similar sandbox on Debian GNU/Linux & Co. without Docker/Podman, you can use bubblewrap (bwrap), which is Linux's equivalent to macOS's sandbox-exec. Bubblewrap provides lightweight containerization with namespace isolation.
Installation
sudo apt install bubblewrap
Sandbox Script
Here's a bubblewrap-based sandbox configuration equivalent to your macOS setup:
# Make executable
chmod +x ~/opencode-sandbox.sh
# Create config directories if they don't exist
mkdir -p ~/.cache/opencode ~/.local/share/opencode \
~/.local/state/opencode ~/.config/opencode
# Run OpenCode in sandbox~/opencode-sandbox.sh
Key Differences from macOS Version
Network isolation: Uses --share-net to allow network access (similar to allow network* in macOS)
Filesystem: Read-only binds for system directories, read-write for workspaces
No full HOME access: Only specific OpenCode directories are accessible
Process isolation: --unshare-all creates new namespaces (PID, mount, IPC, UTS, cgroup)
Alternative: More Restrictive Network Control
If you want to limit network access (e.g., only API calls), you could combine bubblewrap with iptables or nftables rules, though this requires root privileges and is more complex.
Bubblewrap is the other backend that sandbox-runtime is using. For sure you can deal with all those options, but I think it makes a lot of sense to use something like sandbox-runtime to keep that much simpler to use. Plus, you get the network sandboxing with a man in the middle proxy for which you can also specify rules.
Reacted by Pablo Hörtner, Rene Leonhardt and Santiago M. Mola
It is still super simple, and far from user-friendly or finished, but it fulfills my needs for some sense of security while running AI agents, so maybe somebody else also find it useful.
Reacted by Pablo Hörtner, Milan Šulc, drZloy and Davi Medeiros
There's a trade off for these: ~/.shh and ~/.gnupg are often needed so the agent can use git like the user (commit, pull, sign commits) depending on your git config.
Plain Docker doesn't limit outbound traffic by default
True. But it can be configured. And imho that configuration is pretty individual and and not so easy to put in user friendly UIs.
My dockerized setup with aicage let's one pass arguments to the docker run process to configure networking.
@Wuodan fair point on git. One middle ground: keep the key files unreadable, but pass the agent sockets through (SSH_AUTH_SOCK, and the gpg-agent socket for signing). The agent can still commit, pull and sign while it runs, but it can't read the key itself, so nothing can copy it out.
And agreed that network rules are personal. That's probably why a built-in version would start with files only and leave the network side to wrappers like yours.
To restate the request: you'd like OpenCode to run the agent's terminal commands in an OS-level sandbox (like seatbelt on macOS in Codex or Gemini CLI), so they can't read or change files outside the current project. Maintainers will consider it.
OpenCode doesn't have a built-in OS sandbox for shell commands today. What exists now:
The external_directory permission (deny / ask / allow per path) controls OpenCode's own file tools, but it is not enforced at the OS level, so commands run through bash can get around it.
In v2, plugins can rewrite a shell command before it runs (the shellcreate.before hook), so a plugin can wrap commands in sandbox-exec (macOS) or bwrap (Linux). Community plugins such as opencode-sandbox and opencode-seatbelt already take this approach.
Many people in this thread run OpenCode itself inside bwrap, sandbox-exec or a container. Several working scripts are posted in the comments above.
@opencodjr, no the request is for all of opencode and its subprocesses to run in a sandbox, not just the shell tool. For example opencode's reads, writes, and edits should be confined to what the sandbox allows. This guards against a misbehaving or prompt-injected agent compromising or exfiltrating sensitive data. It also guards against misconfigured permissions or vulnerabilities in opencode itself, such that the permission system could be overridden or disabled.
Reacted by Mohamed Abbas Mohamed Elsayed and Matthias Glastra
For anyone landing here: there is a community plugin that does this on both OpenCode v1 and v2, since core still has no sandbox. I maintain it, so disclosure up front.
V2 registers ctx.shell.hook("create.before") and replaces only the shell executable with a generated wrapper: the command, cwd, timeout, permission rules and session history keep their original values. V1 uses the legacy tool.execute.before path, which is lower fidelity and documented as such.
bubblewrap on Linux, Seatbelt (sandbox-exec) on macOS. The workspace is writable, the system read-only, $HOME is synthetic, ambient environment/secrets are cleared, and the network is denied by default.
Fail-closed: if the sandbox cannot be created (missing bwrap, bad profile, broken wrapper), commands are refused instead of silently running unsandboxed. It probes the real wrapper at setup, not just the binary.
Zero runtime dependencies, no proxy, no helper daemon. Deliberate scope: the shell service only. File tools, MCP, LSP and webfetch are not sandboxed, and network is deny/allow with no domain allowlist.
There are integration tests on real runners for both engines (bwrap on Ubuntu, Seatbelt on macOS), so the macOS path is not only unit-tested. If someone here tries it and finds a boundary gap, I would rather hear it in the repo than have the comment stand as a claim.
As many people here pointed out already, nono is working fine with both V1 and V2 - and it is not just a one-person project and trusted by a big community. You will have to adopt the permissions to your needs (as with any such tool), but I have been using it for a while now, and my experience is quite positive. If stronger isolation and access restrictions are needed (e.g., by using a dedicated web proxy that only allows some whitelisted URLs or domains to be accessed), then OpenShell is your friend. Both tools also support other harnesses like Pi or OpenClaw.
Thanks @redtux — no argument that nono and OpenShell are solid, and nono's community is a real advantage. One clarification for anyone comparing, because they sit at a different layer.
nono/OpenShell sandbox the whole agent, so they cover more than my plugin (file tools, MCP, webfetch). The tradeoff is the launch model: nono's V2 docs require --standalone for full containment, and note that it sets OPENCODE_DISABLE_PROJECT_CONFIG=1, disabling project opencode.json, AGENTS.md and project plugins; without it, the client is contained but the background server that runs tools is not guaranteed to be. OpenShell runs the agent in its own container with a gateway/proxy — a different operating model.
opencode-sandbox stays a server plugin: no wrapper, no relaunch, no proxy. The shell is OS-sandboxed (bwrap/Seatbelt), and 0.2.0 adds an in-process tool guard for the file tools and webfetch: workspace/readablePaths/writablePaths confinement, mount precedence, symlink-aware path checks, a webfetch hostname allowlist, and a pre-execution check so write/edit/patch cannot read a target before the policy sees it. It is a policy layer, not an OS boundary, and the README says so plainly. V1 gets a best-effort guard through the legacy tool hook; V2 is the full path.
So: whole-harness + network/credential policy → nono/OpenShell. Zero-friction shell confinement plus an in-process file/webfetch policy in a normal OpenCode install → this plugin. They're complementary, not substitutes. Happy to be corrected on any specific claim.
I use nono with OpenCode V2 in server mode with no issues. I guess using standalone is just a recommendation (due to better isolation/granular control), but I had no issues so far...
Thanks @redtux — fair distinction, and I should have been clearer. --standalone isn't required for nono to work with V2; it's what nono's docs call for when you need full containment. Their warning is that V2 normally connects the client to a background server that owns tool execution, plugins and model requests; without --standalone, nono constrains the client but cannot guarantee that an existing external server is inside the sandbox.
So if you start the opencode serve process under nono too (or otherwise keep tool execution inside the same sandbox), your setup is fine and my caveat doesn't apply. If the server is already running outside nono and the wrapped client connects to it, the sandbox covers the client but not the server that actually runs the tools. That's the case the docs are warning about — not a claim that nono doesn't work.
Out of curiosity: are you launching the server under nono as well, or connecting to one started outside?
Exactly, I have a proper nono profile that allows access to certain external files or directories to be working. Normally nono tells you what's needed, or it tells the agent to run "nono why" in a sandbox. The server is also sandboxed, and MCP is working fine for me (both remote and stdio). For sure it depends on each user's particular setup - e.g. accessing non-root Podman containers isn't always trivial. Allowing the user socket is no issue, but the PID will change after each restart, so you might need a workaround here. Or I had an issue with the codebase-memory-mcp tool as it always wants to access / and /home, but I am using it with supergateway now (similar to mcp-proxy) and access it with type remote instead of stdin from OpenCode. This is working fine, and I have more control over what it can read. I was not arguing against any other solutions or tools btw, just confirming the good experience that other users reported when using nono locally.
I can't recommend nono (from @lukehinds) enough. I use it daily, and I use it with Claude Code at work (since I can't use OpenCode there).
The more I use nono, the more I feel like sandboxing probably shouldn't be a feature of the agent itself (/me ducks). Everyone's config is different. Plugins access different resources, etc.; people use different SSH agents (system agent, 1Password, etc.). There's no way for OpenCode to anticipate a million configuration permutations and provide a sandboxing feature that can accommodate them all and still provide meaningful confinement.
The feature OpenCode actually needs is the ability to be properly sandboxed. That is to say, it is designed with the expectation of running in a sandbox, and it degrades gracefully when it encounters sandbox enforcement-related failures. Maybe even a way to tell the agent process, "you are running confined; adjust your behavior accordingly."
Many years ago I worked for a company that maintained the official SELinux Reference Policy for the US DoD. Every Linux product that we shipped could easily be confined with SELinux because we designed it with confinement in mind. The hard part was confining a process that had never heard of SELinux. E.g., it'd open a file read/write that it only needed to read, then fell on its face when it encountered the denial.
I think the ask should be this: OpenCode should anticipate being sandboxed and behave gracefully when it is. It should even provide guidance and documentation about how to run OpenCode in an arbitrary confined environment and still get the most out of its feature set.
Re: nono and project configs. OPENCODE_DISABLE_PROJECT_CONFIG is no longer set by the nono opencode profile. The profile initially set it because OpenCode V2 would perform a recursive filesystem walk looking for OpenCode config files (and AGENTS.md and other files, I believe; see #52759). When it encountered an access denial, the process blew up. That environment variable prevented the recursive walk but also prevented locating and loading the project-local config. (See above about the agent being designed to be sandboxed.) This OpenCode bug is now fixed, and the nono opencode profile no longer depends on this workaround. I warn you, though, that early V2 releases will blow up because of this.
The following nono run command shows that this variable no longer gets set:
nono run --profile nolabs-ai/opencode --allow-cwd -- sh -c 'env | grep OPENCODE_DISABLE_PROJECT_CONFIG || echo "OPENCODE_DISABLE_PROJECT_CONFIG not set"'
[output abbreviated]
OPENCODE_DISABLE_PROJECT_CONFIG not set
Re: --standalone. The recommendation exists because OpenCode kicks off a server daemon if one doesn't already exist. All instances of OpenCode (CLI, TUI, desktop app) thereafter will opportunistically communicate with that daemon process. If the OpenCode daemon is not sandboxed, even if your CLI/TUI process is sandboxed, then for all intents and purposes, you are running unconfined. This is because the server daemon is the process that takes all actions: file reads/writes, tool calls (including, especially, the bash tool), etc. The --standalone flag says, "don't opportunistically communicate with an existing OpenCode daemon; instead start up a fresh one and communicate only with that one."
I suspect you could get by with something resembling nono run <profile> -- sh -c 'opencode service stop && opencode', which would ensure the OpenCode service daemon starts fresh, inheriting the sandbox. The risk, though, is that you run OpenCode some other way, such as the desktop app, and it connects to a sandboxed OpenCode daemon expecting to do unsandboxed things and hilarity ensues (I haven't experimented with this but it sounds interesting).
Thanks @zcutlip — that's a genuinely useful correction, and you're right. I took the OPENCODE_DISABLE_PROJECT_CONFIG caveat from nono's published OpenCode docs; if the current profile no longer sets it, my comparison was stale. I've corrected the README in a docs-only 0.2.1 and removed the claim that nono disables project config/AGENTS.md/plugins.
The --standalone point is the one I should have led with, and your daemon explanation is clearer than mine: it's not about nono "requiring" a flag to work, it's that the daemon owns tool execution, so wrapping only the client doesn't contain the process doing the work. Your opencode service stop && opencode shape is a sensible way to get a fresh in-sandbox daemon; the desktop-app cross-connection risk is exactly why a first-class "you are confined" contract would help.
I also agree with the broader design point: OpenCode should be expected to run under an arbitrary sandbox and degrade gracefully on denials. A plugin like mine can cover the shell/file-tool surface from inside, but it's a stopgap, not a substitute for whole-process confinement.
@neriousy would it be possible to include that last part about expecting to run under a sandbox be included in the other "duplicate" ticket? @opencodejr can you help?
Activity
github-actions commentedon Aug 25, 2025
This issue might be a duplicate of existing issues. Please check:
exectool as more secure alternative to bash tool #2206: This is a comprehensive feature request for adding sandboxing capabilities to OpenCode, addressing the same core concern about restricting agent access to files and system commands outside the current directory. It discusses security risks with the current bash tool and proposes solutions including sandboxing mechanisms similar to what you're asking about.Feel free to ignore if none of these address your specific case.
rekram1-node commentedon Aug 25, 2025
yeah we need better sandboxing, we try to restrict to cwd but agent can use bash to get around it
TyceHerrman commentedon Oct 25, 2025
Could Anthropic's new sandboxing runtime be used for this? https://github.com/anthropic-experimental/sandbox-runtime
rekram1-node commentedon Oct 25, 2025
Oo thats a good callout we will need to look into that, I wonder how easy it is to hookup
gimbo commentedon Oct 25, 2025
I currently mitigate this by running
opencodeinside a docker container, with bind mounts of just the folders I want it to access (or which it needs); can also restrict network activity too if desired this way. Its a bit fiddly and of course container escape is possible, but better than nothing.dwt commentedon Dec 2, 2025
Docker containers are a good start, but when coding on Mac, you loose native tools, and docker (by itself) does not sandbox network requests, which means secret exfiltration is not mitigated at all. I very much second the attention to the anthropics sandbox-runtime.
robbash commentedon Dec 2, 2025
I started off with docker as well, but as mentioned there's a lot of obstacles, incl. the auto-copy on selection in OpenCode being a big problem.
I've spent some time on the macOs
sandbox-exec, which is the underlying tool anthropic'ssrtis using. The issue I had withsrtis that I would need to build a deny list for reading permissions instead of an allowlist, and therefore used the macOs tool straight away.https://gist.github.com/robbash/84aaa7c4133535b59cbaf0c1761031a4
I don't have a lot of experience with the tool though, and there was a lot of trial and error involved. Happy about feedback.
redtux commentedon Dec 3, 2025
Thanks for sharing! For those here not using macos and ready to test this (had no time to do so yet), here is what the bot says:
To create a similar sandbox on Debian GNU/Linux & Co. without Docker/Podman, you can use bubblewrap (bwrap), which is Linux's equivalent to macOS's
sandbox-exec. Bubblewrap provides lightweight containerization with namespace isolation.Installation
Sandbox Script
Here's a bubblewrap-based sandbox configuration equivalent to your macOS setup:
Usage
Key Differences from macOS Version
--share-netto allow network access (similar toallow network*in macOS)--unshare-allcreates new namespaces (PID, mount, IPC, UTS, cgroup)Alternative: More Restrictive Network Control
If you want to limit network access (e.g., only API calls), you could combine bubblewrap with iptables or nftables rules, though this requires root privileges and is more complex.
Debugging
To troubleshoot, run with verbose output:
This setup provides isolation comparable to Claude Code CLI's sandbox while remaining lightweight and avoiding full container solutions.
dwt commentedon Dec 6, 2025
Bubblewrap is the other backend that sandbox-runtime is using. For sure you can deal with all those options, but I think it makes a lot of sense to use something like sandbox-runtime to keep that much simpler to use. Plus, you get the network sandboxing with a man in the middle proxy for which you can also specify rules.
llucax commentedon Dec 11, 2025
I ended up writing this simple tool: https://github.com/frequenz-floss/contai
It is still super simple, and far from user-friendly or finished, but it fulfills my needs for some sense of security while running AI agents, so maybe somebody else also find it useful.
mdlmarkham commentedon Jan 12, 2026
I'm using https://coder.com/ on ProxMox - it works OK, but it's a little of a hassle to get going.
dwt commentedon Jan 13, 2026
I recently found https://github.com/Use-Tusk/fence which looks like a very nice implementation to build a basic sandbox on.
aemonge commentedon Jan 13, 2026
My grain of salt based on bubblewrap
bwrap-> https://github.com/aemonge/aemonge/blob/main/bin/scoderreneleonhardt commentedon Jan 20, 2026
There's an easy way to improve security on macOS by sandboxing agents with shell scripts.
Can
SandVaultbe integrated into OpenCode?https://github.com/webcoyote/sandvault
88 remaining items
Wuodan commentedon Oct 23, 2026
There's a trade off for these:
~/.shhand~/.gnupgare often needed so the agent can use git like the user (commit, pull, sign commits) depending on your git config.True. But it can be configured. And imho that configuration is pretty individual and and not so easy to put in user friendly UIs.
My dockerized setup with aicage let's one pass arguments to the
docker runprocess to configure networking.balabommablock-cpu commentedon Oct 24, 2026
@Wuodan fair point on git. One middle ground: keep the key files unreadable, but pass the agent sockets through (
SSH_AUTH_SOCK, and thegpg-agentsocket for signing). The agent can still commit, pull and sign while it runs, but it can't read the key itself, so nothing can copy it out.And agreed that network rules are personal. That's probably why a built-in version would start with files only and leave the network side to wrappers like yours.
opencodejr commentedon Oct 29, 2026
Thanks for raising this, @edmBernard!
To restate the request: you'd like OpenCode to run the agent's terminal commands in an OS-level sandbox (like seatbelt on macOS in Codex or Gemini CLI), so they can't read or change files outside the current project. Maintainers will consider it.
OpenCode doesn't have a built-in OS sandbox for shell commands today. What exists now:
external_directorypermission (deny/ask/allowper path) controls OpenCode's own file tools, but it is not enforced at the OS level, so commands run through bash can get around it.shellcreate.beforehook), so a plugin can wrap commands insandbox-exec(macOS) orbwrap(Linux). Community plugins such as opencode-sandbox and opencode-seatbelt already take this approach.bwrap,sandbox-execor a container. Several working scripts are posted in the comments above.Related:
zcutlip commentedon Oct 29, 2026
@opencodjr, no the request is for all of opencode and its subprocesses to run in a sandbox, not just the shell tool. For example opencode's reads, writes, and edits should be confined to what the sandbox allows. This guards against a misbehaving or prompt-injected agent compromising or exfiltrating sensitive data. It also guards against misconfigured permissions or vulnerabilities in opencode itself, such that the permission system could be overridden or disabled.
matglas commentedon Oct 30, 2026
Nono has been working for me on opencode since inception but with v2 and the split it only works with --standalone flag.
It would be great if the design of nono as an architecture would fit the architecture of opencode. With it I feel safe running auto approve.
And I 100% support the last comment on suprocess isolation from start to finish by @zcutlip
Hamza-Abili commentedon Nov 9, 2026
For anyone landing here: there is a community plugin that does this on both OpenCode v1 and v2, since core still has no sandbox. I maintain it, so disclosure up front.
opencode-sandbox — https://github.com/Hamza-Abili/opencode-sandbox · npm
@hamzaabili/opencode-sandboxctx.shell.hook("create.before")and replaces only the shell executable with a generated wrapper: the command, cwd, timeout, permission rules and session history keep their original values. V1 uses the legacytool.execute.beforepath, which is lower fidelity and documented as such.sandbox-exec) on macOS. The workspace is writable, the system read-only,$HOMEis synthetic, ambient environment/secrets are cleared, and the network is denied by default.There are integration tests on real runners for both engines (bwrap on Ubuntu, Seatbelt on macOS), so the macOS path is not only unit-tested. If someone here tries it and finds a boundary gap, I would rather hear it in the repo than have the comment stand as a claim.
redtux commentedon Nov 11, 2026
As many people here pointed out already, nono is working fine with both V1 and V2 - and it is not just a one-person project and trusted by a big community. You will have to adopt the permissions to your needs (as with any such tool), but I have been using it for a while now, and my experience is quite positive. If stronger isolation and access restrictions are needed (e.g., by using a dedicated web proxy that only allows some whitelisted URLs or domains to be accessed), then OpenShell is your friend. Both tools also support other harnesses like Pi or OpenClaw.
Hamza-Abili commentedon Nov 11, 2026
Thanks @redtux — no argument that nono and OpenShell are solid, and nono's community is a real advantage. One clarification for anyone comparing, because they sit at a different layer.
nono/OpenShell sandbox the whole agent, so they cover more than my plugin (file tools, MCP, webfetch). The tradeoff is the launch model: nono's V2 docs require
--standalonefor full containment, and note that it setsOPENCODE_DISABLE_PROJECT_CONFIG=1, disabling projectopencode.json,AGENTS.mdand project plugins; without it, the client is contained but the background server that runs tools is not guaranteed to be. OpenShell runs the agent in its own container with a gateway/proxy — a different operating model.opencode-sandboxstays a server plugin: no wrapper, no relaunch, no proxy. The shell is OS-sandboxed (bwrap/Seatbelt), and 0.2.0 adds an in-process tool guard for the file tools andwebfetch: workspace/readablePaths/writablePathsconfinement, mount precedence, symlink-aware path checks, awebfetchhostname allowlist, and a pre-execution check sowrite/edit/patchcannot read a target before the policy sees it. It is a policy layer, not an OS boundary, and the README says so plainly. V1 gets a best-effort guard through the legacy tool hook; V2 is the full path.So: whole-harness + network/credential policy → nono/OpenShell. Zero-friction shell confinement plus an in-process file/
webfetchpolicy in a normal OpenCode install → this plugin. They're complementary, not substitutes. Happy to be corrected on any specific claim.0.2.0: https://github.com/Hamza-Abili/opencode-sandbox/releases/tag/v0.2.0
redtux commentedon Nov 11, 2026
I use nono with OpenCode V2 in server mode with no issues. I guess using standalone is just a recommendation (due to better isolation/granular control), but I had no issues so far...
Hamza-Abili commentedon Nov 11, 2026
Thanks @redtux — fair distinction, and I should have been clearer.
--standaloneisn't required for nono to work with V2; it's what nono's docs call for when you need full containment. Their warning is that V2 normally connects the client to a background server that owns tool execution, plugins and model requests; without--standalone, nono constrains the client but cannot guarantee that an existing external server is inside the sandbox.So if you start the
opencode serveprocess under nono too (or otherwise keep tool execution inside the same sandbox), your setup is fine and my caveat doesn't apply. If the server is already running outside nono and the wrapped client connects to it, the sandbox covers the client but not the server that actually runs the tools. That's the case the docs are warning about — not a claim that nono doesn't work.Out of curiosity: are you launching the server under nono as well, or connecting to one started outside?
redtux commentedon Nov 11, 2026
Exactly, I have a proper nono profile that allows access to certain external files or directories to be working. Normally nono tells you what's needed, or it tells the agent to run "nono why" in a sandbox. The server is also sandboxed, and MCP is working fine for me (both remote and stdio). For sure it depends on each user's particular setup - e.g. accessing non-root Podman containers isn't always trivial. Allowing the user socket is no issue, but the PID will change after each restart, so you might need a workaround here. Or I had an issue with the codebase-memory-mcp tool as it always wants to access / and /home, but I am using it with supergateway now (similar to mcp-proxy) and access it with type remote instead of stdin from OpenCode. This is working fine, and I have more control over what it can read. I was not arguing against any other solutions or tools btw, just confirming the good experience that other users reported when using nono locally.
zcutlip commentedon Nov 12, 2026
I can't recommend nono (from @lukehinds) enough. I use it daily, and I use it with Claude Code at work (since I can't use OpenCode there).
The more I use
nono, the more I feel like sandboxing probably shouldn't be a feature of the agent itself (/meducks). Everyone's config is different. Plugins access different resources, etc.; people use different SSH agents (system agent, 1Password, etc.). There's no way for OpenCode to anticipate a million configuration permutations and provide a sandboxing feature that can accommodate them all and still provide meaningful confinement.The feature OpenCode actually needs is the ability to be properly sandboxed. That is to say, it is designed with the expectation of running in a sandbox, and it degrades gracefully when it encounters sandbox enforcement-related failures. Maybe even a way to tell the agent process, "you are running confined; adjust your behavior accordingly."
Many years ago I worked for a company that maintained the official SELinux Reference Policy for the US DoD. Every Linux product that we shipped could easily be confined with SELinux because we designed it with confinement in mind. The hard part was confining a process that had never heard of SELinux. E.g., it'd open a file read/write that it only needed to read, then fell on its face when it encountered the denial.
I think the ask should be this: OpenCode should anticipate being sandboxed and behave gracefully when it is. It should even provide guidance and documentation about how to run OpenCode in an arbitrary confined environment and still get the most out of its feature set.
Re: nono and project configs.
OPENCODE_DISABLE_PROJECT_CONFIGis no longer set by the nono opencode profile. The profile initially set it because OpenCode V2 would perform a recursive filesystem walk looking for OpenCode config files (and AGENTS.md and other files, I believe; see #52759). When it encountered an access denial, the process blew up. That environment variable prevented the recursive walk but also prevented locating and loading the project-local config. (See above about the agent being designed to be sandboxed.) This OpenCode bug is now fixed, and the nono opencode profile no longer depends on this workaround. I warn you, though, that early V2 releases will blow up because of this.The following
nono runcommand shows that this variable no longer gets set:Re:
--standalone. The recommendation exists because OpenCode kicks off a server daemon if one doesn't already exist. All instances of OpenCode (CLI, TUI, desktop app) thereafter will opportunistically communicate with that daemon process. If the OpenCode daemon is not sandboxed, even if your CLI/TUI process is sandboxed, then for all intents and purposes, you are running unconfined. This is because the server daemon is the process that takes all actions: file reads/writes, tool calls (including, especially, the bash tool), etc. The--standaloneflag says, "don't opportunistically communicate with an existing OpenCode daemon; instead start up a fresh one and communicate only with that one."I suspect you could get by with something resembling
nono run <profile> -- sh -c 'opencode service stop && opencode', which would ensure the OpenCode service daemon starts fresh, inheriting the sandbox. The risk, though, is that you run OpenCode some other way, such as the desktop app, and it connects to a sandboxed OpenCode daemon expecting to do unsandboxed things and hilarity ensues (I haven't experimented with this but it sounds interesting).Hamza-Abili commentedon Nov 12, 2026
Thanks @zcutlip — that's a genuinely useful correction, and you're right. I took the
OPENCODE_DISABLE_PROJECT_CONFIGcaveat from nono's published OpenCode docs; if the current profile no longer sets it, my comparison was stale. I've corrected the README in a docs-only 0.2.1 and removed the claim that nono disables project config/AGENTS.md/plugins.The
--standalonepoint is the one I should have led with, and your daemon explanation is clearer than mine: it's not about nono "requiring" a flag to work, it's that the daemon owns tool execution, so wrapping only the client doesn't contain the process doing the work. Youropencode service stop && opencodeshape is a sensible way to get a fresh in-sandbox daemon; the desktop-app cross-connection risk is exactly why a first-class "you are confined" contract would help.I also agree with the broader design point: OpenCode should be expected to run under an arbitrary sandbox and degrade gracefully on denials. A plugin like mine can cover the shell/file-tool surface from inside, but it's a stopgap, not a substitute for whole-process confinement.
0.2.1 (docs only): https://github.com/Hamza-Abili/opencode-sandbox/releases/tag/v0.2.1
matglas commentedon Nov 12, 2026
@neriousy would it be possible to include that last part about expecting to run under a sandbox be included in the other "duplicate" ticket? @opencodejr can you help?