{"id":50727108,"url":"https://github.com/marvincaspar/agent-sandbox","last_synced_at":"2026-06-10T05:01:25.526Z","repository":{"id":356457766,"uuid":"1232601083","full_name":"marvincaspar/agent-sandbox","owner":"marvincaspar","description":"Runs AI coding agents inside isolated Docker containers","archived":false,"fork":false,"pushed_at":"2026-06-03T20:47:35.000Z","size":24,"stargazers_count":8,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-03T22:17:50.821Z","etag":null,"topics":["ai","ai-agents","ai-coding-agent","docker","llm","opencode","pi-agent"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marvincaspar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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-05-08T05:01:01.000Z","updated_at":"2026-06-03T20:47:39.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/marvincaspar/agent-sandbox","commit_stats":null,"previous_names":["marvincaspar/agent-sanbox","marvincaspar/agent-sandbox"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/marvincaspar/agent-sandbox","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marvincaspar%2Fagent-sandbox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marvincaspar%2Fagent-sandbox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marvincaspar%2Fagent-sandbox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marvincaspar%2Fagent-sandbox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marvincaspar","download_url":"https://codeload.github.com/marvincaspar/agent-sandbox/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marvincaspar%2Fagent-sandbox/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34137570,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-10T02:00:07.152Z","response_time":89,"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":["ai","ai-agents","ai-coding-agent","docker","llm","opencode","pi-agent"],"created_at":"2026-06-10T05:01:24.296Z","updated_at":"2026-06-10T05:01:25.518Z","avatar_url":"https://github.com/marvincaspar.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Agent Sandbox\n\nRuns AI coding agents inside isolated Docker containers. Agents get no root access, no Docker socket, and no ability to escalate privileges — safe to run on your host machine.\n\n---\n\n## Agents\n\n### pi\n\n[pi](https://pi.dev) is an AI coding agent that runs in the terminal.\n\nAlso mounts `~/.pi/agent` for persistent extensions and auth, `~/.agents/skills` for skills, and forwards API keys and pi-related env vars from the host.\n\n### Installation\n\n```bash\nln -sf \"$(pwd)/pi/pi\" \"/usr/local/bin/pi\"\npi --build\n```\n\n---\n\n## Usage\n\n```bash\n# Run in the current directory (uses the base image, unrestricted network)\npi\n\n# Run with a specific language runtime\npi --lang go\npi --lang php8.4\npi --lang php8.5\n\n# Rebuild all images and run\npi --build\n\n# Enable the proxy sidecar (restricted network access via allowlist)\npi --proxy\n\n# Enable the proxy with a custom allowed-domains list\npi --proxy --allowed-domains /path/to/allowed_domains.txt\n\n# Pass flags directly to the agent\npi -- --help\n```\n\n---\n\n## How it works\n\nEach agent lives in its own directory with a `Dockerfile` and a bash wrapper script. The wrapper:\n\n1. Builds all image variants on first run, or when `--build` is passed\n2. Starts a proxy sidecar container and an isolated internal Docker network\n3. Runs the selected agent variant with strict security settings (`--cap-drop=ALL`, `--no-new-privileges`)\n4. Bind-mounts the current working directory so the agent can read and edit your files\n\nThe Dockerfiles use a multi-stage build based on Microsoft's [`devcontainers/typescript-node`](https://mcr.microsoft.com/en-us/artifact/mar/devcontainers/typescript-node) image:\n\n| Tag      | Contents                                         |\n| -------- | ------------------------------------------------ |\n| `base`   | Node.js + npm, agent, Git, curl, ca-certificates |\n| `go`     | `base` + Go 1.26                                 |\n| `php8.4` | `base` + PHP 8.4                                 |\n| `php8.5` | `base` + PHP 8.5                                 |\n\n### Security model\n\nContainers run as your host UID (non-root), with all Linux capabilities dropped and `no-new-privileges` enforced. Agents cannot install system packages, access the Docker socket, or escape the container via privilege escalation.\n\nNetwork access can optionally be restricted by a proxy sidecar (see [Proxy](#proxy) below). When `--proxy` is passed, the agent container is placed on an isolated internal Docker network with no direct internet access — all outbound traffic is forced through the proxy. Without `--proxy`, the container has unrestricted internet access.\n\n---\n\n## Proxy\n\nThe proxy is a [tinyproxy](https://tinyproxy.github.io/) sidecar container that enforces an allowlist of permitted hostnames. It runs alongside the agent container and is the agent's only path to the internet.\n\n### How it works\n\n1. **Isolated network** — The wrapper creates a dedicated internal Docker network per run. The agent container joins only this network; it has no direct internet access.\n2. **Proxy sidecar** — A `pi-proxy` container starts on both the internal network and the default bridge (so it can reach the internet). The agent's `HTTP_PROXY` / `HTTPS_PROXY` env vars are set to the proxy's address on the internal network.\n3. **Allowlist filtering** — At startup, `entrypoint.sh` reads `~/.agents/proxy_allowed_domains.txt` and converts each entry into a tinyproxy regex filter rule:\n   - `example.com` → exact match (`^example\\.com$`)\n   - `*.example.com` → domain + all subdomains (`^(.*\\.)?example\\.com$`)\n   - Lines starting with `#` and blank lines are ignored\n4. **Default-deny** — Any hostname not matched by the filter is blocked. Only connections to standard HTTPS/HTTP ports are permitted (tinyproxy `ConnectPort`).\n5. **Teardown** — When the agent exits, the wrapper stops the proxy container and removes the network.\n\n### Default allowed domains\n\nThe default allowlist is read from `~/.agents/proxy_allowed_domains.txt`. Example:\n\n```\n# Allowed domains for the pi agent proxy.\n# One entry per line. Wildcards supported: *.example.com\n# Lines starting with # are ignored.\n\n# GitHub\ngithub.com\napi.github.com\nraw.githubusercontent.com\n*.githubusercontent.com\n*.github.com\n\n# Atlassian\n*.atlassian.com\n*.atlassian.net\n\n# Services running on host\nhost.docker.internal\n```\n\nTo use a different file, pass `--allowed-domains /path/to/file`.\n\n### Bypassing the proxy\n\nThe proxy is opt-in — simply omit `--proxy` and the container runs with unrestricted internet access (the default).\n\n```bash\npi  # no proxy, unrestricted network\n```\n\n---\n\n## Jira Auth Flow\n\n### Prerequisites (macOS)\n\nDocker Desktop must have **Host Networking** enabled so the OAuth callback from your browser reaches the container:\n\n\u003e Docker Desktop → Settings → Resources → Network → **Enable host networking**\n\n---\n\n### One-time setup: persist credentials\n\n`~/.config/acli` is already mounted into the container, so credentials survive restarts.\n\n---\n\n### Auth workflow (only needed once, or after token expiry)\n\nRun login command inside the docker container:\n\n```bash\nacli jira auth login --web\n```\n\nThe browser opens automatically. Complete the Atlassian OAuth flow — the callback redirects back to the browser and auth finishes without any manual steps.\n\n**Verify:**\n```bash\nacli jira auth status\n```\n```\n✓ Authenticated\n  Site: your-org.atlassian.net\n  Email: your@email.com\n  Authentication Type: oauth\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarvincaspar%2Fagent-sandbox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarvincaspar%2Fagent-sandbox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarvincaspar%2Fagent-sandbox/lists"}