{"id":46905488,"url":"https://github.com/thomaspeklak/agent-sandbox","last_synced_at":"2026-05-11T09:55:20.527Z","repository":{"id":340941318,"uuid":"1167984810","full_name":"thomaspeklak/agent-sandbox","owner":"thomaspeklak","description":"Sandbox for agents with podman","archived":false,"fork":false,"pushed_at":"2026-05-11T08:09:20.000Z","size":924,"stargazers_count":4,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-11T09:36:46.746Z","etag":null,"topics":["agent","claude-code","codex","linux","opencode","pi-agent","podman","sandbox"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thomaspeklak.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-26T22:29:59.000Z","updated_at":"2026-05-11T08:09:22.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/thomaspeklak/agent-sandbox","commit_stats":null,"previous_names":["thomaspeklak/pi-sandbox","thomaspeklak/agent-sandbox"],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/thomaspeklak/agent-sandbox","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomaspeklak%2Fagent-sandbox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomaspeklak%2Fagent-sandbox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomaspeklak%2Fagent-sandbox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomaspeklak%2Fagent-sandbox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thomaspeklak","download_url":"https://codeload.github.com/thomaspeklak/agent-sandbox/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomaspeklak%2Fagent-sandbox/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32889971,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-10T13:40:02.631Z","status":"online","status_checked_at":"2026-05-11T02:00:05.975Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent","claude-code","codex","linux","opencode","pi-agent","podman","sandbox"],"created_at":"2026-03-11T01:08:28.305Z","updated_at":"2026-05-11T09:55:20.500Z","avatar_url":"https://github.com/thomaspeklak.png","language":"Rust","funding_links":[],"categories":["Container Sandboxes"],"sub_categories":[],"readme":"# agent-sandbox\n\n![agent logos in a sandbox](./agent-sandbox-logo.webp)\n\n`ags` is a Rust CLI that launches AI coding agents inside a rootless Podman sandbox.\n\nIt is designed to keep your host clean while still giving agents controlled access to your repo, selected tools, and selected secrets.\n\n## Documentation map\n\n- `README.md` (this file): quick start + daily usage\n- `docs/COMMANDS.md`: detailed command behavior and side effects\n- `docs/CONFIG.md`: full config schema and semantics\n- `docs/GLIMPSE.md`: user-facing Glimpse/host UI setup and usage\n- `docs/TROUBLESHOOTING.md`: common problems and fixes\n- `docs/ARCHITECTURE.md`: internal architecture overview\n- `CONTRIBUTING.md`: contributor workflow and quality checklist\n\n## What this tool provides\n\n- Rootless containerized agent runs (Podman)\n- Multi-agent support:\n  - `pi`\n  - `claude`\n  - `codex`\n  - `gemini`\n  - `opencode`\n  - `shell` (interactive bash with agent environments mounted)\n- First-run setup for SSH auth + signing keys\n- Persistent per-agent host volumes by default (lockdown uses ephemeral staged homes)\n- Configurable mounts, tool binaries, and secret sources\n- Optional hardened `--lockdown` runs for inspecting untrusted/foreign repos with reduced host exposure\n- Optional browser sidecar support for browser-enabled workflows\n- Auth proxy for secure sandbox browser opens and OAuth loopback callbacks\n- Health checks via `ags doctor`\n- Convenience alias/wrapper generation via `ags create-aliases`\n\n---\n\n## Requirements\n\nRequired on host:\n\n- Rust toolchain (to build/run `ags` from source)\n- Podman (rootless recommended)\n- `git`\n- `ssh-keygen`\n- `ssh-add`\n- `bash`\n\nOptional but useful:\n\n- `make` (for convenience targets)\n- `secret-tool` (GNOME keyring/libsecret integration)\n- Browser executable (for `--browser` mode)\n- `zenity` or `kdialog` (for auth proxy allow/deny prompts; auto-denied if neither is available)\n\n\u003e Tip: run `ags doctor` after setup to verify your environment.\n\n---\n\n## Build and install\n\nFrom repository root:\n\n```bash\n# build debug binary\ncargo build -p ags\n\n# build optimized release binary\ncargo build -p ags --release\n```\n\nRun without installing:\n\n```bash\ncargo run -p ags -- --agent pi\n```\n\nOptional self-link into `~/.local/bin/ags`:\n\n```bash\ncargo run -p ags -- install --link-self\n```\n\nIf an existing file/symlink should be replaced:\n\n```bash\ncargo run -p ags -- install --link-self --force\n```\n\nYou can also use Make targets (see below).\n\n---\n\n## First-time setup\n\n### 1) Install baseline assets and config layout\n\n```bash\ncargo run -p ags -- install\n```\n\nThis writes:\n\n- `~/.config/ags/Containerfile`\n- `~/.config/ags/tmux.conf`\n- `~/.config/ags/pi/extensions/guard.ts`\n- `~/.config/ags/pi/settings.json` (if missing)\n\n### 2) Create and edit config\n\nUse `config/config.example.toml` as your template:\n\n```bash\nmkdir -p ~/.config/ags\ncp config/config.example.toml ~/.config/ags/config.toml\n```\n\nThen replace placeholders with real values and paths.\n\nOptional per-repo overrides can live at:\n\n```text\nPROJECT_ROOT/.ags/config.toml\n```\n\nWhen present, AGS loads your user/global config first, then applies the repo-local overlay. Repo-local scalar/table fields win, while repeatable sections like `[[mount]]` are appended so projects can add mounts without replacing your base config.\n\n### 3) Run setup\n\n```bash\ncargo run -p ags -- setup\n```\n\n`setup` will:\n\n- Generate SSH keys if missing:\n  - `~/.ssh/ags-agent-auth`\n  - `~/.ssh/ags-agent-signing`\n- Print public keys so you can add them to GitHub\n- Ensure Pi guard/settings assets exist in the host path mounted to `/home/dev/.pi`\n- Optionally prompt to store configured secrets via `secret-tool`\n\n### 4) Build/update sandbox image and agent installs\n\n```bash\ncargo run -p ags -- update\ncargo run -p ags -- update-agents\n```\n\n### 5) Verify\n\n```bash\ncargo run -p ags -- doctor\ncargo run -p ags -- --agent shell -- -lc 'br --version \u0026\u0026 bv --version \u0026\u0026 dcg --version \u0026\u0026 tmux -V \u0026\u0026 test -f ~/.tmux.conf'\n```\n\n---\n\n## Quick start (Makefile)\n\nEquivalent convenience flow:\n\n```bash\nmake setup\nmake doctor\nmake update\nmake update-agents\nmake run\n```\n\nAvailable targets:\n\n- `make setup`\n- `make doctor`\n- `make update`\n- `make update-agents`\n- `make run`\n- `make run-browser`\n- `make install`\n- `make install-self`\n- `make uninstall`\n- `make aliases`\n\n---\n\n## Daily usage\n\nRun Pi agent:\n\n```bash\nags --agent pi\n```\n\nRun inside a tmux session (opt-in):\n\n```bash\nags --agent pi --tmux\n```\n\nRun with browser sidecar:\n\n```bash\nags --agent pi --browser\n```\n\nRun in hardened lockdown mode for untrusted repos:\n\n```bash\nags --agent claude --lockdown\n```\n\nLockdown keeps network access and workspace visibility, but disables secrets, SSH agent forwarding, generic config/tool mounts, host bridges/sidecars, and direct mounting of real agent home state. Instead AGS stages a sanitized ephemeral agent home/runtime for the selected agent and discards session/history artifacts when the run exits.\n\nDisable AGS Pi/Claude guards for one run:\n\n```bash\nags --agent pi --yolo\nags --agent claude --yolo\n```\n\nRun other agents:\n\n```bash\nags --agent claude\nags --agent codex\nags --agent gemini\nags --agent opencode\nags --agent shell\n```\n\nPass arguments through to the underlying agent CLI using `--`:\n\n```bash\nags --agent pi -- --continue\nags --agent claude -- --model sonnet\nags --agent claude --defaults -- --model opus\n```\n\nUse `--defaults` / `-D` to prepend AGS-managed passthrough defaults for the selected harness. Today that means Claude gets `--strict-mcp-config --dangerously-skip-permissions`, Gemini gets `--yolo`, and other agents currently add nothing.\n\n### tmux inside the sandbox\n\nThe sandbox image includes `tmux` with a minimal version-controlled config for team-pane workflows.\nDefaults include:\n\n- default prefix remains `Ctrl-b`\n- mouse support enabled\n- pane/window creation starts in the current pane directory\n- `xterm-kitty` terminal support via `kitty-terminfo`\n- no plugin manager dependency\n\nIf you want the agent itself to start inside tmux, pass `--tmux`:\n\n```bash\nags --agent pi --tmux\nags --agent shell --tmux\n```\n\nThis is intentionally **not** the default.\nIf `tmux` is reported as missing when using `--tmux`, rebuild the sandbox image first:\n\n```bash\nags update\n```\n\nQuick check:\n\n```bash\nags --agent shell -- -lc 'tmux -V \u0026\u0026 test -f ~/.tmux.conf \u0026\u0026 tmux new-session -d -s smoke \u0026\u0026 tmux kill-session -t smoke'\n```\n\nUse a non-default config file:\n\n```bash\nags --agent pi --config /path/to/config.toml\n```\n\n### MCP auth persistence\n\nMCP servers that use OAuth (e.g. Linear) store auth tokens in `~/.mcp-auth` inside the container. Without a persistent mount, tokens are lost on every session restart. Add this to your config:\n\n```toml\n[[mount]]\nhost = \"$HOME/.mcp-auth\"\ncontainer = \"/home/dev/.mcp-auth\"\nmode = \"rw\"\nkind = \"dir\"\ncreate = true\n```\n\nTo skip the allow/deny dialog for known OAuth providers:\n\n```toml\n[auth_proxy]\nauto_allow_domains = [\"mcp.linear.app\"]\n```\n\n### Host service access from inside sandbox\n\n`ags` runs agent CLIs **inside the container**, so `localhost` refers to the container itself.\n\nTo connect to services running on your host machine, use `host.containers.internal` instead.\n\n`ags` also exports runtime hints inside the container:\n\n- `AGS_HOST_SERVICES_HOST=host.containers.internal`\n- `AGS_HOST_SERVICES_HINT` (human-readable reminder)\n\nAnd for agents with prompt hooks (`pi`, `claude`, `codex`), `ags` injects a short startup hint into the agent prompt context.\n\nExample:\n\n```bash\nags --agent shell -- -lc 'curl http://host.containers.internal:3000/health'\n```\n\nPostgres example (`psql` is available in the sandbox image after `ags update`):\n\n```bash\nags --agent shell -- -lc 'PGPASSWORD=\"${PGPASSWORD:-postgres}\" psql -h \"${AGS_HOST_SERVICES_HOST}\" -p \"${PGPORT:-5432}\" -U \"${PGUSER:-postgres}\" \"${PGDATABASE:-postgres}\"'\n```\n\nTip: add `PGPASSWORD`, `PGUSER`, `PGDATABASE`, and `PGPORT` to `[sandbox].passthrough_env` if you want host values to flow into the container automatically.\n\n### Host-owned Glimpse windows\n\nIf you want sandboxed agent code to open Glimpse windows on your host desktop, enable `[host_ui]` in your config.\n\nStart here:\n\n- `docs/GLIMPSE.md` for setup and troubleshooting\n- `docs/CONFIG.md` for the `[host_ui]` field reference\n\n---\n\n## Commands reference\n\n### Core commands\n\n- `ags setup` — generate keys, ensure Pi assets in mounted host path, optional keyring secret setup\n- `ags doctor` — run environment + config health checks\n- `ags update` — rebuild container image from `Containerfile` and refresh bundled `br`/`bv`/`dcg` binaries\n- `ags update-agents` — install/update agent CLIs in persistent volumes\n- `ags install [--link-self] [--force] [--add-agent-mounts]` — install assets/config layout, optional self-link, optional config mount block append\n- `ags uninstall` — currently reserved/no-op cleanup\n- `ags create-aliases` — create managed wrappers and/or shell alias blocks\n- `ags completions --shell \u003cbash|zsh|fish\u003e` — print shell completion script\n\n### `create-aliases` options\n\n```bash\nags create-aliases --mode wrappers|aliases|both --shell fish|zsh|bash --force\n```\n\n- default mode: `wrappers`\n- if `--shell` omitted, shell is autodetected from `$SHELL`\n\n### Shell completions\n\n```bash\n# add extra same-path directory mounts for a single run\nags --agent claude -d ~/code -d ~/Downloads\n\n# bash\nags completions --shell bash \u003e ~/.local/share/bash-completion/completions/ags\n\n# zsh\nags completions --shell zsh \u003e ~/.zfunc/_ags\n\n# fish\nags completions --shell fish \u003e ~/.config/fish/completions/ags.fish\n```\n\n### Global run flags\n\n- `--agent \u003cpi|claude|codex|gemini|opencode|shell\u003e` (required for run mode)\n- `--browser`\n- `--tmux`\n- `--stop-when-done` (requires `--tmux`)\n- `--psp`\n- `--psp-keep`\n- `--yolo`\n- `--root`\n- `--lockdown` (harden the run by disabling host bridges, secrets, SSH agent, generic mounts/tools, direct agent-home mounts, host-loopback networking, and adding size-limited tmpfs mounts for that run)\n- `--defaults` / `-D` (prepend AGS-managed passthrough defaults for the selected harness)\n- `--config \u003cpath\u003e`\n- `--add-dir \u003cpath\u003e` / `-d \u003cpath\u003e` (repeatable, run only; still allowed in lockdown)\n\n---\n\n## Configuration guide\n\nDefault base config path:\n\n- `~/.config/ags/config.toml`\n\nOptional repo-local overlay path:\n\n- `PROJECT_ROOT/.ags/config.toml`\n\nIf the base config is missing, `ags` auto-creates a minimal default file on first run.\n\nPrecedence order:\n\n1. user/global config (`~/.config/ags/config.toml`, or `--config \u003cpath\u003e` if provided)\n2. repo-local overlay (`PROJECT_ROOT/.ags/config.toml`) when running inside a git repo/worktree\n\nRepo-local scalar/table fields override the base config. Repeatable sections (`[[mount]]`, `[[agent_mount]]`, `[[tool]]`, `[[secret]]`) are additive.\n\nUse `config/config.example.toml` for full schema examples.\n\n### Important sections\n\n- `[sandbox]`\n  - Container image name and core paths\n  - SSH key paths\n  - bootstrap files\n  - base env passthrough allowlist\n- `[[agent_mount]]`\n  - Dedicated required mounts for agent home-state paths (explicit, no implicit agent mounts)\n- `[[mount]]`\n  - Additional bind mounts from host to container\n  - supports `mode`, `kind`, `when`, `create`, `optional`\n- `[[tool]]`\n  - Tool binary mount\n  - optional nested `[[tool.directory]]` mounts\n  - optional nested `[[tool.secret]]` sources\n- `[[secret]]`\n  - Map env var names to source(s): `from_env` and/or `secret_store`\n- `[auth_proxy]`\n  - `auto_allow_domains`: list of domains to skip the allow/deny prompt for (e.g. `[\"mcp.linear.app\"]`)\n- `[browser]`\n  - Enables browser sidecar integration used with `--browser`\n- `[update]`\n  - Controls Pi package spec and pnpm minimum release age for updates\n\n---\n\n## Security notes\n\n- Use least-privilege, short-lived tokens whenever possible.\n- Only mount what the agent needs.\n- Prefer read-only (`ro`) mounts unless write access is required.\n- For untrusted or foreign repos, prefer `--lockdown` to minimize host exposure for that run.\n- In lockdown, Bash command classification fails closed if `destructive_command_guard` (`dcg`) is unavailable or errors; run `ags doctor`/`ags update` if Bash commands are unexpectedly blocked.\n- Treat `passthrough_env` and configured secrets as sensitive data paths.\n- npm/pnpm lifecycle scripts are disabled in the sandbox (`ignore-scripts=true`).\n- Rotate/revoke credentials quickly if compromise is suspected.\n- The auth proxy requires explicit user approval (via desktop dialog) before opening any URL requested by the sandbox agent. URLs are never opened silently.\n- OAuth loopback callbacks are relayed through the host proxy — the container never listens on host network ports directly.\n- This repo ships a project-local dcg policy (`.dcg/packs/git-worktree-sandbox.yaml`) that blocks `git worktree prune` in sandbox sessions because not all host worktrees are necessarily visible from inside the container.\n\n---\n\n## Project layout\n\n- `crates/ags/` — Rust CLI implementation\n- `config/Containerfile` — base sandbox image definition\n- `config/tmux.conf` — minimal tmux defaults copied into the sandbox image\n- `config/config.example.toml` — full config template\n- `agent/extensions/guard.ts` — runtime guard extension mounted for Pi\n- `agent/settings.example.json` — example Pi settings template\n- `agent/auth-proxy-shim` — container-side `$BROWSER` replacement for auth proxy\n- `Makefile` — convenience command wrappers\n\n---\n\n## Troubleshooting\n\n- Run `ags doctor` first.\n- If image is missing/stale: run `ags update`.\n- If agent CLIs are missing/stale: run `ags update-agents`.\n- If browser mode fails:\n  - ensure `[browser].enabled = true`\n  - verify `[browser].command` is valid\n  - verify debug port is available\n- If auth proxy prompts are auto-denied: install `zenity` or `kdialog`\n- If secrets are not found:\n  - verify env vars exist and are non-empty\n  - or verify `secret-tool` entries match configured attributes\n\n---\n\n## Contributing\n\nContributions are welcome.\n\nFor the full contributor guide, see [`CONTRIBUTING.md`](./CONTRIBUTING.md).\n\n### Development setup\n\n```bash\n# build\ncargo build -p ags\n\n# format\ncargo fmt\n\n# lint\ncargo clippy -p ags -- -D warnings\n\n# test\ncargo test -p ags\n```\n\n### Suggested PR workflow\n\n1. Create a focused branch.\n2. Make small, clear commits.\n3. Add/update tests for behavior changes.\n4. Run fmt/clippy/tests locally.\n5. Update docs (README/config example/help text) when behavior changes.\n6. Open PR with:\n   - summary of user-visible changes\n   - config/migration notes (if any)\n   - test coverage notes\n\n### High-value contribution areas\n\n- Better diagnostics in `doctor`\n- Config schema/documentation improvements\n- Additional agent/profile support\n- Better cross-platform behavior and install UX\n- Safer defaults and security hardening\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomaspeklak%2Fagent-sandbox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthomaspeklak%2Fagent-sandbox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomaspeklak%2Fagent-sandbox/lists"}