Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Note: This is a personal project configured for my use case that I made public in case anybody else finds it useful. You will need to edit the Dockerfile (and the languages/tools baked into the image) to match your setup.

opencode-sbx

A single self-contained folder that wraps opencode in an isolated rootless podman container, so the AI coding agent can only see the current project folder and its own shared config.

No per-project scaffolding. No docker-compose. No extra users to create. Build the image once, then cd into any project and run opencode-sbx.

Requirements

  • podman. The wrapper is designed for rootless podman; running it with rootful podman will likely create files owned by root on the host. Verify rootless podman works with podman info (no root needed).
  • bash on the host.

Setup

# from anywhere
opencode-sbx setup          # builds localhost/opencode-sbx:latest

# one-time: add the folder to PATH (the installer doesn't do this for you)
echo 'export PATH="$PATH:/work/opencode-sbx"' >> ~/.bashrc
# then `source ~/.bashrc` or open a new shell

The build bakes in your host UID/GID so files created inside the container are owned by you on the host. If your UID/GID ever changes, rerun setup.

Daily use

cd /any/project
opencode-sbx                # opens opencode against the current folder
opencode-sbx -- uname -r    # run a one-off command inside the container
opencode-sbx verify         # show isolation state

Opencode configuration, credentials (auth.json from /connect), sessions, snapshots, and runtime state are shared across all projects at three host-side dirs:

  • ${XDG_CONFIG_HOME:-~/.config}/opencode-sbx/ — opencode config (opencode.json, agents, etc.)
  • ${XDG_DATA_HOME:-~/.local/share}/opencode-sbx/ — auth, sessions, snapshots
  • ${XDG_STATE_HOME:-~/.local/state}/opencode-sbx/ — model history, prompt history, and other runtime state

All three respect the standard XDG_CONFIG_HOME / XDG_DATA_HOME / XDG_STATE_HOME env vars (default to ~/.config / ~/.local/share / ~/.local/state when unset).

Only the project source tree ($PWD/work) is per-project. Configure providers once via /connect and every project picks them up.

Tunables (env vars)

Variable Default Purpose
OPENCODE_SBX_CPUS 4 Container CPU quota
OPENCODE_SBX_RAM 4g Container memory limit

Example: OPENCODE_SBX_CPUS=2 OPENCODE_SBX_RAM=2g opencode-sbx

What's in the image

Alpine Linux edge with: opencode (installed at build time via the official installer — no curl|bash at runtime), git, nodejs, npm, python3, py3-pip, .NET SDK (latest LTS via the dot.net install script — invariant globalization, telemetry opted out), rust/cargo/rustfmt/ clippy (via rustup — latest stable, --no-modify-path), make, gcc, musl-dev, gcompat, vim, openssh-client. Edit Dockerfile and run opencode-sbx rebuild to tweak. Rebuild pulls latest opencode, latest stable Rust, and latest .NET LTS.

Security model — read this

Ultimately, this is just a plain rootless podman container so ensure it fits your security model.

Three namespaces isolate the agent from your host:

  1. Mount namespace — only $PWD (at /work) and the shared opencode config/data/state dirs are visible. Your ~/.ssh, ~/.aws, other projects, /etc/shadow — none are mounted in. Opencode state (config, auth, sessions, snapshots, model history) is shared across all projects by design; only the project source tree differs per run.
  2. User namespace — container UID 0 maps to your host UID only, not host root. With --userns=keep-id --user UID:GID, the agent runs as a non-root user inside the container.
  3. Network namespace — rootless NAT; the container can reach the network (so opencode can call the model API) but is not a peer on your host LAN.

Important caveat: the container shares the host kernel. A container escape via a host-kernel privilege-escalation bug would land the attacker as your host user in one step. There is no separate guest-kernel barrier.

In practice this is a reasonable sandbox for an AI coding agent you are spot-checking. For genuinely untrusted code (which can include AI-generated code), use a full VM instead.

The $PWD (host project) mount uses :z only — it is not recursively chowned. If files in your project dir are owned by another host user, the agent may see permission errors. The shared opencode config/data/state dirs are chowned to the container user.

Files

File Purpose
opencode-sbx Wrapper script (executable, add folder to PATH)
Dockerfile Alpine image definition
entrypoint.sh Execs CMD (opencode is baked in at build time)
README.md This file

Commands

Command What it does
opencode-sbx Launch opencode in $PWD
opencode-sbx -- <cmd>... One-off command inside the container
opencode-sbx setup Build the image (run once)
opencode-sbx build Same as setup
opencode-sbx rebuild Rebuild image (no cache)
opencode-sbx verify Show UID, mounts, isolation caveat
opencode-sbx help Usage message

About

A simple rootless podman wrapper to start opencode inside a container from a one liner

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages