{"id":51167094,"url":"https://github.com/navapbc/ai-coding-assistant-sandboxing","last_synced_at":"2026-06-26T20:30:27.409Z","repository":{"id":365520228,"uuid":"1268045872","full_name":"navapbc/ai-coding-assistant-sandboxing","owner":"navapbc","description":"Guides and ready-to-use configs for running Claude Code, OpenAI Codex, and GitHub Copilot in strong, low-friction isolation on macOS. Experimental.","archived":false,"fork":false,"pushed_at":"2026-06-17T17:52:49.000Z","size":126,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-17T18:26:01.847Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/navapbc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","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-06-13T04:56:41.000Z","updated_at":"2026-06-17T17:53:12.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/navapbc/ai-coding-assistant-sandboxing","commit_stats":null,"previous_names":["navapbc/ai-coding-assistant-sandboxing"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/navapbc/ai-coding-assistant-sandboxing","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/navapbc%2Fai-coding-assistant-sandboxing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/navapbc%2Fai-coding-assistant-sandboxing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/navapbc%2Fai-coding-assistant-sandboxing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/navapbc%2Fai-coding-assistant-sandboxing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/navapbc","download_url":"https://codeload.github.com/navapbc/ai-coding-assistant-sandboxing/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/navapbc%2Fai-coding-assistant-sandboxing/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34832916,"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-26T02:00:06.560Z","response_time":106,"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":[],"created_at":"2026-06-26T20:30:24.747Z","updated_at":"2026-06-26T20:30:27.392Z","avatar_url":"https://github.com/navapbc.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Sandboxing AI Coding Assistants on macOS\n\n\u003e [!WARNING]\n\u003e **Experimental — work in progress.** This repo is an early, evolving reference, not a finished standard. Expect breaking changes; feedback and PRs welcome.\n\u003e\n\u003e **These sandboxing tools are immature and have real limitations.** The mechanisms this repo relies on (Copilot's local sandbox, Docker Sandboxes, Seatbelt profiles, hostname-based egress proxies) are new, changing fast, and **not designed to contain a determined adversary**. Where they help, they raise the cost of an attack rather than remove it — and whether any given config helps *at all* depends on your version, your setup, and bugs neither you nor the vendor have found yet. **The configs and guidance in this repo may themselves be incomplete, out of date, or simply wrong** — they are written against fast-moving tools and have not been independently audited. Treat them as starting points to review, adapt, and **verify for yourself** against authoritative sources, **not drop-in guarantees**.\n\u003e\n\u003e **Do not develop a false sense of security.** A sandbox that is enabled is not the same as a sandbox that is working as you assume, and \"more secure than nothing\" is not a property you can take for granted. **Verify every claim before you rely on it** — against the linked vendor docs *and* by testing the actual behavior on your own machine (see the [egress check](docs/troubleshooting.md#verify-your-egress-is-actually-default-deny) and [threat-model.md](docs/threat-model.md)). Vendor docs can be wrong or out of date, defaults change between versions, and a config that protected you yesterday may silently stop doing so after an update. Assume nothing is enforced until you have watched it block something.\n\n**Status:** experimental · last reviewed 2026-06-13\n\nGuides and runnable configurations for using **Claude Code**, **OpenAI Codex**, and **GitHub Copilot** safely on developer Macs in an environment that handles sensitive beneficiary data. The goal: an agent that is compromised by prompt injection **cannot read host secrets and cannot exfiltrate data** — while staying pleasant enough to use that nobody routes around it.\n\n## The model in one paragraph\n\nWe do not try to predict what commands an agent will run. We **contain** what any command can touch: the filesystem is scoped to the workspace, network egress is **default-deny** against a short, code-reviewed domain allowlist, and a handful of outward-acting commands (`git push`, `gh pr create`, `npm publish`) keep a human approval step. Everything else runs without prompts, because the OS-enforced boundary — not a permission dialog — is what protects you. Anthropic measured ~84% fewer permission prompts under this model while containing a deliberately compromised agent.\n\n## Three tiers\n\n| Tier | What | Covers | Start here |\n|------|------|--------|------------|\n| **1 — Hardened built-ins** | Each tool's own OS-level sandbox, configured tight | Claude Code (CLI + IDEs), Codex (CLI + VS Code), Copilot CLI (preview) | [claude-code](docs/claude-code.md) · [codex](docs/codex.md) · [copilot](docs/copilot.md) |\n| **2 — Universal isolation** | Devcontainer with default-deny firewall, the `srt` wrapper, or Docker Sandboxes (`sbx`) for the Docker-licensed subset | **All three tools**, including the gaps (Copilot in JetBrains) | [devcontainer](docs/devcontainer.md) · [srt](docs/universal-sandbox-srt.md) · [docker-sandbox](docs/docker-sandbox.md) |\n| **3 — Org enforcement** | MDM-deployed managed settings that developers can't override | Fleet-wide | [enforcement](docs/enforcement.md) |\n\nTiers compose: a developer on Tier 1 today is protected; Tier 3 makes sure it stays on; Tier 2 covers the tools and IDE surfaces that have no built-in story.\n\n\u003e [!WARNING]\n\u003e **Secrets in your shell environment defeat the sandbox.** The OS sandboxes confine the filesystem and network but **not environment variables** — a `GITHUB_TOKEN` (or AWS key) exported in your `~/.zshrc` is inherited by every command the agent runs, sandbox or not. Don't put tokens in dotfiles or the environment. Use a repo-scoped, least-privilege credential kept in a credential store: **[Git credentials guide](docs/git-credentials.md)**.\n\n## Platform support\n\n| Mechanism | Supported on |\n|-----------|--------------|\n| Seatbelt built-ins (`/sandbox`, Codex, `srt`, `agent.sb`) | macOS 13+ (Ventura and later), Apple Silicon and Intel |\n| Docker Sandboxes (`sbx`) | macOS per Docker's requirements (recent macOS, Apple Silicon) — verify your version |\n| Devcontainer | any Docker-compatible runtime (Colima, Docker Desktop, …) |\n\nTwo caveats worth knowing: Apple has **deprecated `sandbox-exec`** (still shipped and used by Codex/Chrome, but a long-term risk — the `srt` and built-in tiers don't depend on the CLI), and **native Windows isn't covered** by these built-in sandboxes (Claude Code needs WSL2). This repo targets an all-macOS fleet.\n\n## Quick install (one prompt + restart)\n\nFrom inside Claude Code or Codex — or any coding agent with a terminal — paste this prompt:\n\n\u003e Clone `navapbc/ai-coding-assistant-sandboxing` with `gh repo clone`, then run `./setup.sh` from the checkout and tell me which tools to restart.\n\nThe agent clones the repo, runs the installer, and reports back; you restart the tool and you're done. `setup.sh` detects which tools you have, installs the user-level baselines from `configs/`, and prints what to restart. Run `./setup.sh --dry-run` first to preview, and re-run after a `git pull` to update.\n\nThe installer configures **Claude Code and Codex**. **Copilot is not file-configured** — there's nothing safe to write unattended, so `setup.sh` only prints guidance. Enable Copilot's sandbox separately: `/sandbox enable` per session in the CLI, or the VS Code terminal-sandbox setting — see [Manual setup](#manual-setup-per-tool) and [copilot.md](docs/copilot.md).\n\n\u003e [!IMPORTANT]\n\u003e **That baseline is not default-deny egress on its own** — `allowedDomains` in user settings only *pre-allows* (skips prompts); an auto-allowed agent can still reach unlisted domains. For **host-level default-deny** (what most solo devs want), run `./setup.sh --managed` **yourself in a terminal** afterward — it deploys the strict managed policy (Claude Code + Codex) and needs `sudo`, so the agent above can't do it. Verify with the [egress check](docs/troubleshooting.md#verify-your-egress-is-actually-default-deny) (`cms.gov` must fail). Details: [Single machine](docs/enforcement.md#single-machine-solo-developer-no-mdm). Prefer not to touch system files? The [devcontainer](docs/devcontainer.md) tier is default-deny without it.\n\nIt never destroys an existing config. For Claude Code's JSON it **deep-merges** the baseline into your file (our security keys win on conflicts, lists are unioned, your other settings are preserved), shows a **diff**, and **asks before writing — defaulting to no**, backing up the original first; `--yes` applies without prompting. For Codex's TOML there's no safe automatic merge, so an existing config is **left completely untouched** — the installer drops a `config.toml.sandbox-baseline` sidecar and shows which keys to add. Real Codex enforcement comes from MDM-deployed `requirements.toml` ([enforcement](docs/enforcement.md)), not from editing each developer's `config.toml`.\n\nTwo design notes so this stays robust:\n\n- **Private repo:** `gh repo clone` uses the developer's existing GitHub auth, so a private repo just works — no special handling, and only authorized people can pull it.\n- **No URL in the flow:** the slug above is the *only* reference to the repo's location, and it lives in this one place. Once cloned, `setup.sh` installs from the files next to it and never refers back to where it came from — so the repo moving (or being renamed; `gh` follows GitHub's rename redirects) doesn't break anything.\n\n## Manual setup (per tool)\n\n- **Claude Code** → run `/sandbox`, then copy [`configs/claude-code/settings.user.json`](configs/claude-code/settings.user.json) to `~/.claude/settings.json`. Done in 5 minutes. **For host-level default-deny egress (most solo devs want this), also run `./setup.sh --managed`** — the user baseline alone is *not* default-deny ([why \u0026 how](docs/enforcement.md#single-machine-solo-developer-no-mdm)). [Guide](docs/claude-code.md)\n- **Codex CLI** → copy [`configs/codex/config.toml`](configs/codex/config.toml) to `~/.codex/config.toml`. [Guide](docs/codex.md)\n- **Copilot CLI** → run `/sandbox enable` in a session (public preview); for VS Code set [`configs/copilot/vscode-settings.json`](configs/copilot/vscode-settings.json). **Copilot agent mode in JetBrains has no sandbox — use the [devcontainer](docs/devcontainer.md).** [Guide](docs/copilot.md)\n- **Any tool, any IDE — strongest isolation** → the [devcontainer](docs/devcontainer.md) ([`configs/devcontainer/`](configs/devcontainer/)): a **~10-minute [quick start](docs/devcontainer.md#quick-start-10-minutes--mostly-the-one-time-image-build)** to a sandboxed agent in VS Code or JetBrains — the whole process behind default-deny egress. Or — if you have Docker — [Docker Sandboxes](docs/docker-sandbox.md) (`sbx`), the preferred Tier 2 for that subset.\n\n## Documentation map\n\n**Most developers need only two things: the [Quick install](#quick-install-one-prompt--restart) above and their tool's guide ([Claude Code](docs/claude-code.md) · [Codex](docs/codex.md) · [Copilot](docs/copilot.md)).** Everything below is reference — reach for it when you hit a wall or you're on the platform/security team.\n\n| Doc | Read it when |\n|-----|--------------|\n| [threat-model.md](docs/threat-model.md) | You want to know exactly what we're defending against — and what sandboxing does *not* solve |\n| [claude-code.md](docs/claude-code.md) | Setting up Claude Code's built-in sandbox (CLI, VS Code, JetBrains) |\n| [codex.md](docs/codex.md) | Setting up Codex's sandbox modes and permission profiles |\n| [copilot.md](docs/copilot.md) | Copilot CLI/VS Code sandboxing and the JetBrains gap |\n| [universal-sandbox-srt.md](docs/universal-sandbox-srt.md) | Wrapping *any* CLI in a Seatbelt + filtering-proxy sandbox (`srt`), plus our raw `sandbox-exec` fallback |\n| [devcontainer.md](docs/devcontainer.md) | Running agents in a container with a default-deny egress firewall |\n| [docker-sandbox.md](docs/docker-sandbox.md) | Docker Sandboxes (`sbx`) — microVM + hostname-filtering proxy, for the Docker-licensed subset |\n| [git-credentials.md](docs/git-credentials.md) | Storing least-privilege GitHub tokens on macOS (1Password / Keychain) — and keeping them out of your shell environment |\n| [agent-git.md](docs/agent-git.md) | How an agent commits/branches in each tier, the monorepo `.git`-in-workspace fix, and how push is gated — consistently across tools |\n| [network-allowlists.md](docs/network-allowlists.md) | The full domain reference: what's allowed, what's never allowed, and why |\n| [enforcement.md](docs/enforcement.md) | Platform team: MDM, managed settings, config precedence, defense-in-depth layering |\n| [policy-matrix.md](docs/policy-matrix.md) | The one-page approved / not-approved matrix per tool and surface |\n| [troubleshooting.md](docs/troubleshooting.md) | Something was blocked, or a tool fails inside the sandbox |\n\n## Principles\n\n1. **Default-deny egress, everywhere.** There is no deny list — anything not on the short allowlist is blocked. Cloud-provider storage domains (`*.amazonaws.com`, `*.googleapis.com`, `*.blob.core.windows.net`, …) are **never** allowlisted: they are multi-tenant endpoints where an attacker controls a bucket.\n2. **Contain, don't enumerate.** No command allowlisting. The bet is that the sandbox boundary — not a list of approved commands — is what limits the blast radius, so commands run freely *within* it; only boundary-piercing (`docker`) and outward-acting (`git push`) commands keep a human in the loop. How much that contains depends on the boundary actually holding — see principle 4.\n3. **Fast unblock or it doesn't survive.** Allowlist changes are a one-line, code-reviewed PR — hours, not tickets. A slow exception process is how developers end up disabling security tools.\n4. **Honest about residual risk.** The built-in proxies filter by hostname without inspecting TLS (Docker Sandboxes is the exception — it TLS-terminates); `github.com` is itself multi-tenant. See [threat-model.md](docs/threat-model.md) before treating any of this as absolute.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnavapbc%2Fai-coding-assistant-sandboxing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnavapbc%2Fai-coding-assistant-sandboxing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnavapbc%2Fai-coding-assistant-sandboxing/lists"}