Is there a way to sandbox the agent ? #1487

Open
opened 2026-02-16 17:31:13 -05:00 by yindo · 16 comments
Owner

Originally created by @edmBernard on GitHub (Aug 25, 2025).

Originally assigned to: @thdxr on GitHub.

Hi,

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,

Originally created by @edmBernard on GitHub (Aug 25, 2025). Originally assigned to: @thdxr on GitHub. Hi, 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,
Author
Owner

@github-actions[bot] commented on GitHub (Aug 25, 2025):

This issue might be a duplicate of existing issues. Please check:

  • #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.

@github-actions[bot] commented on GitHub (Aug 25, 2025): This issue might be a duplicate of existing issues. Please check: - #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.
Author
Owner

@rekram1-node commented on GitHub (Aug 25, 2025):

yeah we need better sandboxing, we try to restrict to cwd but agent can use bash to get around it

@rekram1-node commented on GitHub (Aug 25, 2025): yeah we need better sandboxing, we try to restrict to cwd but agent can use bash to get around it
Author
Owner

@TyceHerrman commented on GitHub (Oct 25, 2025):

Could Anthropic's new sandboxing runtime be used for this? https://github.com/anthropic-experimental/sandbox-runtime

@TyceHerrman commented on GitHub (Oct 25, 2025): Could Anthropic's new sandboxing runtime be used for this? https://github.com/anthropic-experimental/sandbox-runtime
Author
Owner

@rekram1-node commented on GitHub (Oct 25, 2025):

Oo thats a good callout we will need to look into that, I wonder how easy it is to hookup

@rekram1-node commented on GitHub (Oct 25, 2025): Oo thats a good callout we will need to look into that, I wonder how easy it is to hookup
Author
Owner

@gimbo commented on GitHub (Oct 25, 2025):

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.

@gimbo commented on GitHub (Oct 25, 2025): 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.
Author
Owner

@dwt commented on GitHub (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.

@dwt commented on GitHub (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.
Author
Owner

@robbash commented on GitHub (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'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.

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.

@robbash commented on GitHub (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'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. 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.
Author
Owner

@redtux commented on GitHub (Dec 2, 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

sudo apt install bubblewrap

Sandbox Script

Here's a bubblewrap-based sandbox configuration equivalent to your macOS setup:

#!/bin/bash
# Save as ~/opencode-sandbox.sh and chmod +x it

# Define your workspace directories
WORKSPACES=(
    "$HOME/Development/docker"
    "$HOME/Development/dotnet"
    "$HOME/Development/node"
)

# Build workspace bind mounts
WORKSPACE_BINDS=()
for ws in "${WORKSPACES[@]}"; do
    if [ -d "$ws" ]; then
        WORKSPACE_BINDS+=(--bind "$ws" "$ws")
    fi
done

# Execute OpenCode in sandbox
bwrap \
    --unshare-all \
    --share-net \
    --die-with-parent \
    --new-session \
    \
    `# Basic filesystem structure` \
    --ro-bind /usr /usr \
    --ro-bind /lib /lib \
    --ro-bind /lib64 /lib64 \
    --ro-bind /bin /bin \
    --ro-bind /sbin /sbin \
    --symlink usr/lib /lib \
    --symlink usr/lib64 /lib64 \
    --symlink usr/bin /bin \
    --symlink usr/sbin /sbin \
    --proc /proc \
    --dev /dev \
    --tmpfs /tmp \
    --tmpfs /run \
    \
    `# Minimal /etc files needed` \
    --ro-bind /etc/resolv.conf /etc/resolv.conf \
    --ro-bind /etc/hosts /etc/hosts \
    --ro-bind /etc/nsswitch.conf /etc/nsswitch.conf \
    --ro-bind /etc/passwd /etc/passwd \
    --ro-bind /etc/group /etc/group \
    --ro-bind /etc/localtime /etc/localtime \
    \
    `# SSL certificates for API access` \
    --ro-bind /etc/ssl /etc/ssl \
    --ro-bind-try /etc/ca-certificates /etc/ca-certificates \
    \
    `# Home directory structure` \
    --dir "$HOME" \
    --setenv HOME "$HOME" \
    --chdir "$HOME" \
    \
    `# OpenCode config and cache directories (read-write)` \
    --bind-try "$HOME/.cache/opencode" "$HOME/.cache/opencode" \
    --bind-try "$HOME/.local/share/opencode" "$HOME/.local/share/opencode" \
    --bind-try "$HOME/.local/state/opencode" "$HOME/.local/state/opencode" \
    --bind-try "$HOME/.config/opencode" "$HOME/.config/opencode" \
    \
    `# Workspace directories (read-write)` \
    "${WORKSPACE_BINDS[@]}" \
    \
    `# Terminal and environment` \
    --setenv TMPDIR /tmp \
    --setenv PATH /usr/local/bin:/usr/bin:/bin \
    \
    `# Run OpenCode` \
    opencode "$@"

Usage

# 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

  1. Network isolation: Uses --share-net to allow network access (similar to allow network* in macOS)
  2. Filesystem: Read-only binds for system directories, read-write for workspaces
  3. No full HOME access: Only specific OpenCode directories are accessible
  4. 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.

Debugging

To troubleshoot, run with verbose output:

strace -f ~/opencode-sandbox.sh 2>&1 | grep -i "denied\|error"

This setup provides isolation comparable to Claude Code CLI's sandbox while remaining lightweight and avoiding full container solutions.

@redtux commented on GitHub (Dec 2, 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 ```bash sudo apt install bubblewrap ``` ## Sandbox Script Here's a bubblewrap-based sandbox configuration equivalent to your macOS setup: ```bash #!/bin/bash # Save as ~/opencode-sandbox.sh and chmod +x it # Define your workspace directories WORKSPACES=( "$HOME/Development/docker" "$HOME/Development/dotnet" "$HOME/Development/node" ) # Build workspace bind mounts WORKSPACE_BINDS=() for ws in "${WORKSPACES[@]}"; do if [ -d "$ws" ]; then WORKSPACE_BINDS+=(--bind "$ws" "$ws") fi done # Execute OpenCode in sandbox bwrap \ --unshare-all \ --share-net \ --die-with-parent \ --new-session \ \ `# Basic filesystem structure` \ --ro-bind /usr /usr \ --ro-bind /lib /lib \ --ro-bind /lib64 /lib64 \ --ro-bind /bin /bin \ --ro-bind /sbin /sbin \ --symlink usr/lib /lib \ --symlink usr/lib64 /lib64 \ --symlink usr/bin /bin \ --symlink usr/sbin /sbin \ --proc /proc \ --dev /dev \ --tmpfs /tmp \ --tmpfs /run \ \ `# Minimal /etc files needed` \ --ro-bind /etc/resolv.conf /etc/resolv.conf \ --ro-bind /etc/hosts /etc/hosts \ --ro-bind /etc/nsswitch.conf /etc/nsswitch.conf \ --ro-bind /etc/passwd /etc/passwd \ --ro-bind /etc/group /etc/group \ --ro-bind /etc/localtime /etc/localtime \ \ `# SSL certificates for API access` \ --ro-bind /etc/ssl /etc/ssl \ --ro-bind-try /etc/ca-certificates /etc/ca-certificates \ \ `# Home directory structure` \ --dir "$HOME" \ --setenv HOME "$HOME" \ --chdir "$HOME" \ \ `# OpenCode config and cache directories (read-write)` \ --bind-try "$HOME/.cache/opencode" "$HOME/.cache/opencode" \ --bind-try "$HOME/.local/share/opencode" "$HOME/.local/share/opencode" \ --bind-try "$HOME/.local/state/opencode" "$HOME/.local/state/opencode" \ --bind-try "$HOME/.config/opencode" "$HOME/.config/opencode" \ \ `# Workspace directories (read-write)` \ "${WORKSPACE_BINDS[@]}" \ \ `# Terminal and environment` \ --setenv TMPDIR /tmp \ --setenv PATH /usr/local/bin:/usr/bin:/bin \ \ `# Run OpenCode` \ opencode "$@" ``` ## Usage ```bash # 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 1. **Network isolation**: Uses `--share-net` to allow network access (similar to `allow network*` in macOS) 2. **Filesystem**: Read-only binds for system directories, read-write for workspaces 3. **No full HOME access**: Only specific OpenCode directories are accessible 4. **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. ## Debugging To troubleshoot, run with verbose output: ```bash strace -f ~/opencode-sandbox.sh 2>&1 | grep -i "denied\|error" ``` This setup provides isolation comparable to Claude Code CLI's sandbox while remaining lightweight and avoiding full container solutions.
Author
Owner

@dwt commented on GitHub (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.

@dwt commented on GitHub (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.
Author
Owner

@llucax commented on GitHub (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.

@llucax commented on GitHub (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.
Author
Owner

@mdlmarkham commented on GitHub (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.

@mdlmarkham commented on GitHub (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.
Author
Owner

@dwt commented on GitHub (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.

@dwt commented on GitHub (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.
Author
Owner

@aemonge commented on GitHub (Jan 13, 2026):

My grain of salt based on bubblewrap bwrap -> https://github.com/aemonge/aemonge/blob/main/bin/scoder

@aemonge commented on GitHub (Jan 13, 2026): My grain of salt based on bubblewrap `bwrap` -> https://github.com/aemonge/aemonge/blob/main/bin/scoder
Author
Owner

@reneleonhardt commented on GitHub (Jan 20, 2026):

There's an easy way to improve security on macOS by sandboxing agents with shell scripts.
Can SandVault be integrated into OpenCode?
https://github.com/webcoyote/sandvault

Security Model

The sandvault user:

  • Cannot access your home directory
  • Runs with standard user privileges
  • Cannot modify system files
  • Has its own isolated home directory
@reneleonhardt commented on GitHub (Jan 20, 2026): There's an easy way to improve security on macOS by sandboxing agents with shell scripts. Can `SandVault` be integrated into OpenCode? https://github.com/webcoyote/sandvault > #### Security Model > > The sandvault user: > > * Cannot access your home directory > * Runs with standard user privileges > * Cannot modify system files > * Has its own isolated home directory
Author
Owner

@aemonge commented on GitHub (Jan 27, 2026):

Just in case anyone want's an update on my grain of salt, my last version of scoder implements the wrapper using bubblewrap with optional Landlock defense-in-depth. -> https://github.com/aemonge/aemonge/blob/main/bin/scoder

@aemonge commented on GitHub (Jan 27, 2026): Just in case anyone want's an update on my grain of salt, my last version of `scoder` implements the wrapper using bubblewrap with **optional Landlock** defense-in-depth. -> https://github.com/aemonge/aemonge/blob/main/bin/scoder
Author
Owner

@johannes-qvarford commented on GitHub (Feb 13, 2026):

Hello, thanks to the team for all your hard work! 😊

The existing solutions of os-level isolation for opencode are all well and good (I think I spotted 5+ repos named opencode-sandbox on github). I myself can take any one of them and get something that works for me.

The problem for me is that it does introduce friction that might be too much for the average user - it makes it harder for me to recommend opencode to other people in my organisation compared to say Claude Code or OpenAI Codex.
Also, if people find security annoying, they are just going to ignore it whether we like it or not.

Isolating in a docker container isn't frictionless because of the OS mismatch for OS X and Windows. While you can run the TUI, can you run the Desktop GUI through the docker container somehow?

As mentioned above, Anthropic's experimental sandbox-runtime does easy filesystem isolation, and domain whitelisting which covers all of my concerns at least.
The Visual Studio Code extension looks for opencode on the PATH, so you could sneak in a script earlier in the PATH to wrap the real opencode in the sandbox-runtime. For ACP in IntelliJ IDEA - the most user-friendly option for picking an ACP server doesn't let you do this hijacking I think. But if you opt for manual configuration, then it is possible to pick the hijacking script.

I think that all this headache would go away if opencode supported sandboxing natively. e.g. if opencode used the sandbox-runtime library on startup and spawned itself wrapped in the sandbox (with some option passed to prevent recursion). Some config option could be added to enable this, since it's not backwards-compatible.

If something like this was desirable, I might be able to assist with an MR unless I'm severely underestimating the complexity of this.

@johannes-qvarford commented on GitHub (Feb 13, 2026): Hello, thanks to the team for all your hard work! 😊 The existing solutions of os-level isolation for opencode are all well and good (I think I spotted 5+ repos named opencode-sandbox on github). I myself can take any one of them and get something that works for me. The problem for me is that it does introduce friction that might be too much for the average user - it makes it harder for me to recommend opencode to other people in my organisation compared to say Claude Code or OpenAI Codex. Also, if people find security annoying, they are just going to ignore it whether we like it or not. Isolating in a docker container isn't frictionless because of the OS mismatch for OS X and Windows. While you can run the TUI, can you run the Desktop GUI through the docker container somehow? As mentioned above, Anthropic's experimental sandbox-runtime does easy filesystem isolation, and domain whitelisting which covers all of my concerns at least. The Visual Studio Code extension looks for opencode on the PATH, so you could sneak in a script earlier in the PATH to wrap the real opencode in the sandbox-runtime. For ACP in IntelliJ IDEA - the most user-friendly option for picking an ACP server doesn't let you do this hijacking I think. But if you opt for manual configuration, then it is possible to pick the hijacking script. I think that all this headache would go away if opencode supported sandboxing natively. e.g. if opencode used the sandbox-runtime library on startup and spawned itself wrapped in the sandbox (with some option passed to prevent recursion). Some config option could be added to enable this, since it's not backwards-compatible. If something like this was desirable, I might be able to assist with an MR unless I'm severely underestimating the complexity of this.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#1487