# Recipes Concrete invocations. `pi` below is whatever you aliased to `ai-sandbox`. ## A first session ```bash cd ~/Projects/myapp ai-sandbox doctor # is this machine ready? pi --allow api.anthropic.com --env ANTHROPIC_API_KEY ``` Same thing, but remembered by the repo (so teammates review the policy, not just your shell history): ```bash mkdir -p .ai-sandbox printf 'api.anthropic.com\n' > .ai-sandbox/allow pi --env ANTHROPIC_API_KEY ``` ## Per harness ```bash # pi (baked into the image) pi --allow api.anthropic.com --env ANTHROPIC_API_KEY # pi with a proxy/harness you pass explicitly pi --harness 'pi --model sonnet' --allow api.anthropic.com --env ANTHROPIC_API_KEY # OpenAI Codex CLI (install it into the image with --install or use a custom base) pi --allow chatgpt.com --allow api.openai.com --env OPENAI_API_KEY # Claude Code pi --allow api.anthropic.com --env ANTHROPIC_API_KEY --env CLAUDE_CODE_OAUTH_TOKEN # just a shell in the sandbox pi --shell # any other build/test command, no network needed pi --net none -- make test ``` ## Per ecosystem Only the endpoints the tool actually needs. Everything else stays blocked, so a typosquatted package from an unexpected host fails loudly instead of quietly working. ```bash # npm / node pi --allow registry.npmjs.org --allow nodejs.org --allow github.com # python: pypi needs both of these (the CDN that serves the files is separate) pi --allow pypi.org --allow files.pythonhosted.org # rust pi --allow crates.io --allow static.crates.io --allow index.crates.io # go pi --allow proxy.golang.org --allow sum.golang.org # docker/podman images from within a build pi --allow registry-1.docker.io --allow auth.docker.io --allow production.cloudflare.docker.com # a project that also needs its dev database (non-HTTP: pinned IP + port) pi --allow api.anthropic.com --allow 10.20.0.5:5432 --env ANTHROPIC_API_KEY ``` ## Git ```bash # fetch/push over https with a token in the environment pi --allow github.com --env GH_TOKEN -- git push origin main # ssh: the key has to be mounted deliberately (an explicit, reviewable grant) pi --allow github.com --mount ~/.ssh:ro -- git push origin main # read-only view of a sibling repo for context pi --allow api.anthropic.com --env ANTHROPIC_API_KEY --mount ../docs:/docs:ro ``` ## Tightening a run ```bash # nothing persistent, nothing readable, nothing writable outside the repo pi --net none --ephemeral-home --read-only -- make build # an entirely blank sandbox for untrusted code pi --net none --no-cwd --ephemeral-home --read-only -- bash # CI-ish: refuse to start if the policy or environment is not exactly right pi --strict-args --net allow --allow-file .ai-sandbox/allow --env-file .ci/env -- npm ci ``` ## Long-lived gate shared by several sandboxes ```bash ai-sandbox gate up --allow api.anthropic.com --allow registry.npmjs.org # name=aisb-gate # port=18081 # proxy_env=export HTTPS_PROXY=http://100.64.0.1:18081 ai-sandbox --proxy 100.64.0.1:18081 --allow api.anthropic.com --shell ai-sandbox gate logs # what did it allow/deny? ai-sandbox gate down ``` ## Debugging ```bash ai-sandbox --dry-run --allow example.com --env KEY # the exact podman invocation ai-sandbox --print-policy # effective policy, no secrets ai-sandbox --print-entrypoint | less # the enforcement script ai-sandbox --keep --net none -- false # leave the container for forensics ai-sandbox ps AISB_GATE_KEEP=1 pi --allow example.com --shell # keep the gate after exit ai-sandbox clean --all # "the ruleset would not install" (exit 77): check the host podman info | grep -i rootless grep "$(id -un)" /etc/subuid ``` ## Making it the default for a project `.ai-sandbox/config`: ```ini net = allow harness = pi cpus = 8 memory = 8g mount = ../specs:/specs:ro env = ANTHROPIC_API_KEY ``` `.ai-sandbox/allow`: ``` api.anthropic.com registry.npmjs.org ``` Then `pi` alone in that directory is the whole invocation — and because both files are in the repository, the sandbox policy gets reviewed with the code.