add ai-sandbox: rootless podman sandbox for agentic development
A single bash script that runs a coding harness (pi by default) inside a rootless Ubuntu 24.04 container with only the current directory mounted at /project, an explicit egress allowlist and an explicit environment: nothing is passed in that was not named on the command line or in a config file. Network enforcement here is empirical rather than assumed (tests/spike_network.sh, docs/networking.md). The original design -- a sidecar proxy on an internal network -- does not work rootless on this host, so allow mode runs pasta with --map-host-loopback, installs an inet aisb ruleset inside the container that drops every egress path except the gate's, and relays through a squid gate bound to the host's loopback that resolves names itself and refuses anything unlisted. The entrypoint checks that the default-drop rule really exists before setpriv drops to uid 1000 with an empty capability set, and exits 77/78 rather than run unenforced. The Containerfile, the entrypoint, the squid config generator and the ruleset renderer all live in bin/ai-sandbox, and the image is tagged by content hash, so a policy change can never silently reuse a stale image. Tests are pure bash: 161 assertions start no container and touch no network, 256 run real ones, including proof that a raw socket, a stripped proxy env and DNS all stay blocked while an allowlisted host works over both http and CONNECT. LLM-Generated: true
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
# ai-sandbox -- development tasks. Everything runs with the tools already on this
|
||||
# machine plus podman; nothing needs to be installed system-wide.
|
||||
SHELL := /bin/bash
|
||||
BIN := bin/ai-sandbox
|
||||
SHELLCHECK_IMAGE := docker.io/koalaman/shellcheck:stable
|
||||
|
||||
.PHONY: help test e2e check lint style doctor build clean-demo all
|
||||
help: ## show this help
|
||||
@grep -hE '^[a-zA-Z_-]+:.*?## ' $(MAKEFILE_LIST) | awk -F':.*?## ' '{printf " %-12s %s\n", $$1, $$2}'
|
||||
|
||||
test: ## unit tests only (no containers, no network)
|
||||
./tests/run.sh
|
||||
|
||||
e2e: ## everything, including real containers and real egress tests
|
||||
./tests/run.sh --e2e
|
||||
|
||||
check: lint test ## lint + unit tests (what CI would run)
|
||||
|
||||
lint: ## shellcheck every shell file, in a container (nothing installed locally)
|
||||
@podman run --rm -v "$(CURDIR):/src:ro,z" -w /src $(SHELLCHECK_IMAGE) \
|
||||
--severity=warning --shell=bash --exclude=SC1091 \
|
||||
bin/ai-sandbox install.sh tests/run.sh tests/lib.sh tests/spike_network.sh \
|
||||
$$(ls tests/unit/*.sh tests/e2e/*.sh) \
|
||||
&& echo "shellcheck: clean"
|
||||
|
||||
style: ## bash-style syntax check of every shell file (fast, no deps)
|
||||
@for f in $(BIN) install.sh tests/*.sh tests/unit/*.sh tests/e2e/*.sh; do \
|
||||
[ -f "$$f" ] || continue; bash -n "$$f" || exit 1; \
|
||||
done; echo "bash -n: clean"
|
||||
|
||||
doctor: ## verify this machine can run the sandbox
|
||||
@$(BIN) doctor
|
||||
|
||||
build: ## build the sandbox and gate images
|
||||
@$(BIN) build --gate
|
||||
|
||||
clean-demo: ## remove sandbox containers, gates and stale session files
|
||||
@$(BIN) clean --all
|
||||
Reference in New Issue
Block a user