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 observed process exec events to the unified audit log:
~/.local/state/opencode-sandbox/runs/<run-id>/audit-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