Files
opencode-sandbox/bin/opencode-sandbox
T
k.denisov 01fc1627c1 Protect host-run files from the agent; trust registry; git audit
- read-only in the sandbox: .opencode-sandbox/, .cc-safety-net/, .git/hooks, .git/config,
  an in-project core.hooksPath, the egress rules and the safety-net home; .git is pinned
  by a bind onto itself so it cannot be swapped
- only trusted projects are loaded (init / trust): a .opencode-sandbox/ in a worktree or a
  subdirectory is no longer sourced on the host
- run (before and after the session) and doctor report planted .git entries, redirected
  worktrees and per-worktree overrides
- hide Firefox, Claude, VS Code, Cursor and Codex configs
2026-10-30 01:31:36 -07:00

99 lines
2.6 KiB
Bash
Executable File

#!/usr/bin/env bash
# opencode-sandbox — run OpenCode 2 for a project inside a sandbox:
# egress filter (squid in a container) + netlock (nftables by group) + bubblewrap.
# See README.md. Start with: opencode-sandbox help
set -euo pipefail
OCSB_HOME="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/.." && pwd)"
export OCSB_HOME
# shellcheck source-path=SCRIPTDIR/..
# shellcheck source=lib/common.sh
source "${OCSB_HOME}/lib/common.sh"
usage() {
cat <<'EOF'
Usage: opencode-sandbox <command> [args]
Project setup
init Create .opencode-sandbox/ in the current git repository
trust [dir] Trust an existing .opencode-sandbox/ (a clone): its config runs on the host
config Print the effective configuration
doctor Check dependencies and host setup
Running
run [opencode args] Prepare everything and start OpenCode (web UI) in the sandbox
prepare Egress filter up + netlock check + self-tests, without OpenCode
Egress filter (squid)
egress up|down|status|logs|verify|render
Netlock (blocks direct egress for the agent group; setup/teardown need sudo)
netlock setup|teardown|status|verify
Worktrees
wt add <branch> [hook args] Create a worktree (runs .opencode-sandbox/hooks/wt-post-add)
wt rm <name|path> [--force] Remove a worktree (runs .opencode-sandbox/hooks/wt-pre-rm)
wt list
Environment: OCSB_<SETTING>=... overrides any setting for one run (see `config`).
EOF
}
command_name="${1:-help}"
[[ $# -gt 0 ]] && shift
case "${command_name}" in
init)
source "${OCSB_HOME}/lib/init.sh"
ocsb_init "$@"
;;
trust)
ocsb_trust "$@"
;;
config)
ocsb_load_project
ocsb_print_config
;;
doctor)
source "${OCSB_HOME}/lib/doctor.sh"
ocsb_doctor "$@"
;;
run)
ocsb_load_project
source "${OCSB_HOME}/lib/egress.sh"
source "${OCSB_HOME}/lib/netlock.sh"
source "${OCSB_HOME}/lib/run.sh"
ocsb_prepare
ocsb_run "$@"
;;
prepare)
ocsb_load_project
source "${OCSB_HOME}/lib/egress.sh"
source "${OCSB_HOME}/lib/netlock.sh"
source "${OCSB_HOME}/lib/run.sh"
ocsb_prepare
;;
egress)
ocsb_load_project
source "${OCSB_HOME}/lib/egress.sh"
ocsb_egress "$@"
;;
netlock)
ocsb_load_project --optional
source "${OCSB_HOME}/lib/netlock.sh"
ocsb_netlock "$@"
;;
wt)
ocsb_load_project
source "${OCSB_HOME}/lib/worktree.sh"
ocsb_wt "$@"
;;
help | -h | --help)
usage
;;
*)
usage >&2
ocsb_die "unknown command: ${command_name}"
;;
esac