opencode-sandbox: OpenCode 2 in a sandbox for any project
Runs OpenCode 2 with full permissions while containing its mistakes: - egress filter: squid in a container per project; squid.conf is rendered from layered egress.conf files (package, user, project, local) with allow/block/connect rules and expect-pass/expect-block self-tests - netlock: nftables rejects direct egress for the opencode-sandbox group (installed once with sudo as a systemd unit) - bubblewrap: read-only host, writable project, worktrees and state; credentials hidden; ssh keys via the host's ssh-agent; session bus replaced by an xdg-dbus-proxy limited to notifications; no permission prompts (sudo and systemd-run denied); refuses to run unsandboxed - per-project state in ~/.local/share/opencode-sandbox/<name> - worktrees: `wt add|rm|list` with project hooks - skills mounted per project; the opencode-sandbox skill explains the environment to the agent - plugins as submodules: context-panel, skill-compact-resurrect; global config adds opencode-notifier and cc-safety-net - README in English and Russian
This commit is contained in:
Executable
+94
@@ -0,0 +1,94 @@
|
||||
#!/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
|
||||
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 "$@"
|
||||
;;
|
||||
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
|
||||
Reference in New Issue
Block a user