A Go CLI wrapper that runs OpenCode inside Apple's native container runtime on macOS, with configurable network policy and domain blocklisting.
# Quick setup
curl -fsSL https://raw.githubusercontent.com/RabbITCybErSeC/opencode-sandbox/main/install.sh | bash# Add the alias printed by the installer, then check your environment
sopencode doctor
# Create configs
sopencode init --global
sopencode init
# Fetch the published default image
sopencode image pull
# Run OpenCode in the sandbox
sopencode run .
# Or forward OpenCode args directly
sopencode --help
sopencode .Manual development checkout:
git clone https://github.com/RabbITCybErSeC/opencode-sandbox.git
cd opencode-sandbox
git pull --ff-only
go build -o ./opencode-sandbox ./cmd/opencode-sandbox
# Check your environment
./opencode-sandbox doctor
# Create configs
./opencode-sandbox init --global
./opencode-sandbox init
# Fetch the published default image
./opencode-sandbox image pull
# Or build the image locally from source
./opencode-sandbox image build
# Run OpenCode in the sandbox
./opencode-sandbox run .
# Or forward OpenCode args directly
./opencode-sandbox --help
./opencode-sandbox .For a fuller setup guide, including local CLI build, config paths, skill import, and strict eBPF setup, see Quickstart.
Command audit logging is opt-in while the custom init image path is experimental. When enabled, the init daemon attaches eBPF exec tracepoints inside the Apple container Linux VM and writes every observed process exec to:
~/.local/state/opencode-sandbox/runs/<run-id>/command-events.jsonl
The log includes full argv by default, so it may contain URLs, prompts, tokens, or other command-line secrets. If a run hangs at Apple container startup and the boot log mentions /sbin/vminitd, disable command audit and use practical proxy mode until the init image is rebuilt.
audit:
commands:
enabled: true
backend: ebpf
failClosed: false
logArgs: full
excludeExecutables:
- /usr/bin/trueShell builtins that do not spawn a process are not separate exec events.
Blocks configured domains via an HTTP CONNECT proxy inside the container. Easy to set up and suitable for daily development.
network:
mode: practical
backend: proxy
blocklist:
- "*.segment.io"Connect to MCP servers or other services running on your Mac from inside the sandbox:
# One-off
opencode-sandbox run . --allow-host-access
# Or persist in .opencode-sandbox.yaml
network:
localhostAccess:
enabled: trueOne-time host setup (until reboot):
sudo container system dns create host.container.internal --localhost 203.0.113.113Then use http://host.container.internal:3000 in your opencode.json MCP config.
IPv4 cgroup/connect enforcement inside the Apple container Linux VM. Requires a strict init image.
network:
mode: strict
backend: ebpf
defaultAction: allow
blocklist:
- "*.telemetry.example.com"
ebpf:
initImage: ghcr.io/rabbitcybersec/opencode-sandbox-init:latest
networkName: opencode-sandboxDefault-allow strict mode blocks configured exact-domain IPv4 destinations after resolution and allows unknown traffic. Default-deny blocks unknown IPv4 destinations and should be used only with an allowlist plan.
During active development, use a short wrapper alias:
alias sopencode='opencode-sandbox'Then run:
sopencode run .Direct OpenCode argument forwarding is supported, so you can alias opencode itself when you are ready:
alias opencode='opencode-sandbox'- Network Policy — practical vs strict eBPF, configuration, event logs
- Quickstart — first install, config, image pull/build, and run
- OpenCode Config Control — wrapper config paths and sandbox-managed OpenCode config/state
- Security Model — threat model, isolation layers, limitations
- Troubleshooting — doctor checks, common issues, fixes
- Implementation Spec — architecture and design decisions
go test ./...Published images can be pulled with:
opencode-sandbox image pull
opencode-sandbox image pull --strict-initLocal source builds remain supported:
opencode-sandbox image build
opencode-sandbox image build --strict-initLive integration tests (require Apple container and macOS):
OPENCODE_SANDBOX_LIVE=1 go test -tags live ./internal/integration/...MIT