{"slug": "show-hn-code-airlock-run-claude-code-and-codex-in-disposable-microvms", "title": "Show HN: Code Airlock: Run Claude Code and Codex in Disposable MicroVMs", "summary": "Code Airlock, a new open-source tool, lets developers run coding agents like Claude Code and Codex inside disposable microVMs to prevent direct host access while allowing agents to install packages and run tests autonomously. The tool wraps Docker Sandboxes to provide a read-only host repo and commit-based review workflow, aiming to balance agent autonomy with security.", "body_md": "Run Claude Code, Codex, OpenCode, or another coding agent in a disposable microVM, then review its work as normal git commits.\n\nCode Airlock is a small wrapper around [Docker Sandboxes](https://docs.docker.com/ai/sandboxes/) for people who want to let coding agents work with fewer prompts without giving them direct access to the host machine.\n\nCoding agents are most useful when they can install packages, run tests, inspect failures, and iterate without asking before every command. That is also exactly when you want a stronger boundary than process-level deny rules.\n\nCode Airlock keeps the workflow simple:\n\n| You want | Code Airlock does |\n|---|---|\n| Run agents unattended | Starts the selected agent inside a Docker Sandbox microVM |\n| Keep your local repo clean | Uses clone mode, so the host repo is mounted read-only |\n| Review everything first | Pulls sandbox commits back with `fetch` , `diff` , and `merge` |\n| Limit network access | Can apply a configurable allowlist for model APIs and package registries |\n| Switch agents | Uses `AGENT=claude` , `AGENT=codex` , `AGENT=opencode` , and other Docker Sandbox agents |\n\nCoding agents are most effective when they can use the tools needed to finish the task: install dependencies, inspect generated files, run test suites, start local services, read logs, and iterate on failures. Over-constraining every shell command often turns the agent into a slower autocomplete loop.\n\nCode Airlock moves the main safety boundary below the agent. The agent can work with more autonomy inside a disposable microVM, while the host repo stays read-only and the resulting changes still come back as commits for review.\n\nYou can. Code Airlock is intentionally a thin wrapper around Docker Sandboxes, not a replacement for it.\n\nUse `sbx`\n\ndirectly when you want full control over sandbox lifecycle, policies, kits, and one-off experiments. Use Code Airlock when you want the common coding-agent loop already wired together:\n\n- clone mode by default\n- stable sandbox naming per repo\n- one-command agent startup\n- repo-local\n`AGENTS.md`\n\nscaffolding `fetch`\n\n,`diff`\n\n,`review`\n\n, and`merge`\n\ncommands for the sandbox branch- a documented credential and network-policy path for Claude Code, Codex, and OpenCode\n\nThe point is to make the safe workflow boring and repeatable while still leaving `sbx`\n\navailable underneath.\n\nAgent harness rules are useful, and Code Airlock is meant to work with them. Codex approvals, Claude Code permissions, OpenCode settings, `AGENTS.md`\n\n, and custom prompts all help shape what the agent should do.\n\nThose rules are still policy inside the agent process. They do not give you a disposable VM, a read-only host repo, a separate clone for agent commits, or a host-side review step before changes land. They also do not provide a shared wrapper for Claude Code, Codex, OpenCode, and other agents.\n\nCode Airlock treats harness rules as the first layer and Docker Sandboxes as the boundary underneath it. The agent can be configured to behave well; the sandbox limits what happens when it does not.\n\nInstall Docker Sandboxes first. On Linux:\n\n```\ncurl -fsSL https://get.docker.com | sudo REPO_ONLY=1 sh\nsudo apt-get install docker-sbx\nsudo usermod -aG kvm $USER\nnewgrp kvm\nsbx login\n```\n\nOn macOS and Windows, follow Docker's [official install guide](https://docs.docker.com/ai/sandboxes/get-started/).\n\nInstall Code Airlock with npm:\n\n```\nnpm install -g code-airlock\n```\n\nOr with Homebrew (head-only formula until a tagged release exists):\n\n```\nbrew tap trivo25/code-airlock https://github.com/Trivo25/code-airlock\nbrew install --HEAD code-airlock\n```\n\nOnce the CLI is installed, it can walk you through any missing prerequisites:\n\n```\ncode-airlock setup   # guided install; shows each command and asks before running it\ncode-airlock doctor  # checks only, changes nothing\n```\n\nOr use the standalone shell installer:\n\n```\ncurl -fsSL https://raw.githubusercontent.com/Trivo25/code-airlock/main/install.sh | sh\n```\n\nThe shell installer also adds a short `codelock`\n\nalias when that command is not already taken:\n\n```\ncodelock up\ncodelock status\ncodelock attach\n```\n\nThe npm package intentionally installs only `code-airlock`\n\n, because `codelock`\n\nis already an npm package name. Add a personal shell alias if you want the shorter command after npm install:\n\n```\nalias codelock=code-airlock\n```\n\nOr clone it manually:\n\n```\ngit clone https://github.com/Trivo25/code-airlock.git\ncd code-airlock\nln -s \"$PWD/code-airlock\" ~/.local/bin/code-airlock\n```\n\nThe installer writes to `~/.local/bin`\n\nby default. Choose another location with:\n\n```\ncurl -fsSL https://raw.githubusercontent.com/Trivo25/code-airlock/main/install.sh | PREFIX=/usr/local/bin sh\n```\n\nSkip or rename the short alias:\n\n```\ncurl -fsSL https://raw.githubusercontent.com/Trivo25/code-airlock/main/install.sh | CODE_AIRLOCK_INSTALL_ALIAS=0 sh\ncurl -fsSL https://raw.githubusercontent.com/Trivo25/code-airlock/main/install.sh | CODE_AIRLOCK_ALIAS=calock sh\n```\n\nThe shortest loop, one command in and ordinary Git review out:\n\n```\ncode-airlock run \"add pagination to the users endpoint and run the tests\"\ncode-airlock diff\ncode-airlock merge\n```\n\n`run`\n\nstarts the sandbox like `up`\n\nand hands the task to the agent's non-interactive mode: `-p`\n\nfor Claude Code, `exec --dangerously-bypass-approvals-and-sandbox`\n\nfor Codex, and `run`\n\nfor OpenCode. Other agents receive the task as a plain argument.\n\nAlready using a coding agent? Send it this:\n\n```\nInstall Code Airlock in this environment, then run its first-run checks.\n\nUse npm when available:\nnpm install -g code-airlock\n\nIf npm is unavailable, use:\ncurl -fsSL https://raw.githubusercontent.com/Trivo25/code-airlock/main/install.sh | sh\n\nAfter install, make sure code-airlock is on PATH, then run:\ncode-airlock doctor\ncode-airlock --dry-run up\n\nDo not start a real sandbox or change network policy unless I explicitly ask.\n```\n\nRun it from the repo you want the agent to work on:\n\n```\ncd ~/code/my-project\ncode-airlock doctor       # check sbx, virtualization, login, and git\ncode-airlock --dry-run up # preview the sbx commands without running them\ncode-airlock init         # optional: add starter AGENTS.md instructions\ncode-airlock up           # start Claude Code in a sandbox\ncode-airlock --seed-config up # optionally copy user-level agent customizations\ncode-airlock status       # see this repo's sandbox and tmux session\n```\n\nOn a remote server, keep the agent running after your SSH connection closes:\n\n```\ncode-airlock --tmux up # detach with Ctrl-b, then d\ncode-airlock attach    # reattach later\n```\n\nUse another agent:\n\n```\ncode-airlock --agent codex up\ncode-airlock --agent opencode run \"fix the build\"\n```\n\nThe `AGENT`\n\nenvironment variable and the `sandbox.conf`\n\nsetting still work; the `--agent`\n\nflag wins when both are set.\n\nWhen the agent has made changes, review them from your host:\n\n```\ncode-airlock fetch\ncode-airlock diff\ncode-airlock review      # optional: open a visual diff\ncode-airlock merge\n```\n\nPrefer a pull request over a local merge:\n\n```\ncode-airlock pr                    # push the sandbox branch and open a PR\ncode-airlock pr main feature/foo   # explicit base and branch name\n```\n\nThe push happens from the host with your credentials, so the sandbox still needs no GitHub access. `pr`\n\nuses `gh`\n\nwhen it is installed and prints the GitHub compare URL otherwise. The default branch name is `code-airlock/<sandbox-name>`\n\n; override it with the second argument or `PR_BRANCH`\n\n.\n\nCode Airlock starts Docker Sandboxes with `--clone`\n\n:\n\n- Docker creates a private clone inside the sandbox VM.\n- The agent edits and commits inside that clone.\n- Your host repo stays read-only while the agent runs.\n- You fetch the sandbox branch into your local repo and review the diff.\n- You merge only when you are satisfied.\n\nIf initialized submodules exist, `fetch`\n\n, `diff`\n\n, `review`\n\n, and `merge`\n\nalso try to import each sandbox submodule's `HEAD`\n\ncommit into the matching host submodule. Submodule commits are fetched into:\n\n```\nrefs/remotes/code-airlock/<sandbox-name>\n```\n\nThis lets the parent repo merge point at submodule commits that the host can actually check out. Disable this with `FETCH_SUBMODULES=0`\n\nfor parent-only fetch behavior.\n\nThis means uncommitted sandbox edits do not come back through the normal flow. If needed, enter the sandbox and commit first:\n\n```\ncode-airlock shell\ngit status\ngit add -A\ngit commit -m \"describe the agent work\"\nexit\n```\n\nThen fetch and review from the host.\n\nMost setup failures come from missing Docker Sandboxes, missing KVM/virtualization support, or an unauthenticated `sbx`\n\nCLI. Check before launching:\n\n```\ncode-airlock doctor\n```\n\nPreview what Code Airlock would run without creating a sandbox:\n\n```\ncode-airlock --dry-run up\n```\n\nDry-run mode prints the `sbx`\n\nand git commands instead of running them. It is useful on machines that cannot run KVM yet, or when you want to understand the workflow before creating a VM.\n\nUse `--tmux`\n\nto start the sandboxed agent inside a host-side tmux session:\n\n```\ncode-airlock --tmux up\n```\n\nThis attaches immediately so you can talk to the coding agent. To disconnect without stopping it, press `Ctrl-b`\n\n, then `d`\n\n. This detaches your terminal and leaves the agent running in the tmux session. Reattach later with:\n\n```\ncode-airlock attach\n```\n\nFor an unattended server run, start the tmux session without attaching:\n\n```\ncode-airlock --tmux-detached up\n```\n\nThe default session name is `code-airlock-<sandbox-name>`\n\n. Override it with:\n\n```\nTMUX_SESSION=agent-work code-airlock --tmux up\nTMUX_SESSION=agent-work code-airlock attach\n```\n\nFor a visual review, use:\n\n```\ncode-airlock review\n```\n\nThis fetches the sandbox branch and opens a Git directory diff using VS Code by default. Your working tree is not modified by the review command.\n\nUse another Git difftool:\n\n```\nREVIEW_TOOL=opendiff code-airlock review\nREVIEW_TOOL=vimdiff code-airlock review\n```\n\nAgents work better when the repo contains concise project instructions. Code Airlock can create a starter file:\n\n```\ncode-airlock init\n```\n\nThis writes `AGENTS.md`\n\nin the target repo only if one does not already exist. `code-airlock up`\n\nwill mention the command when no `AGENTS.md`\n\nis present, but it will not silently modify your working tree.\n\nBy default, a sandbox starts with a fresh agent home directory. Project files that are committed to Git come through clone mode, but personal commands, skills, subagents, and global instructions from your host home directory do not.\n\nOpt in to copying curated user-level config before the agent starts:\n\n```\ncode-airlock --seed-config up\n```\n\nThis changes startup from one `sbx run`\n\ncall to:\n\n```\nsbx create --clone ...\nsbx cp ...\nsbx run --name ...\n```\n\nDefault seeded paths:\n\n| Agent | Paths |\n|---|---|\n| Claude Code | `~/.claude/CLAUDE.md` , `~/.claude/commands/` , `~/.claude/agents/` , `~/.claude/skills/` |\n| Codex | `~/.codex/AGENTS.md` , `~/.codex/AGENT.md` , `~/.codex/agents/` , `~/.codex/skills/` , `~/.codex/prompts/` |\n| OpenCode | `~/.config/opencode/AGENTS.md` , `~/.config/opencode/opencode.jsonc` , `~/.config/opencode/commands/` , `~/.config/opencode/agents/` , `~/.config/opencode/skills/` |\n\nCode Airlock does not copy auth files, histories, logs, caches, session state, or `node_modules`\n\nby default. Credentials should still go through Docker Sandboxes' secret manager.\n\nCopy explicit extra user-level paths with:\n\n```\nSEED_PATHS=\"$HOME/.codex/config.toml,$HOME/.claude/settings.json\" code-airlock --seed-config up\n```\n\n`SEED_PATHS`\n\nentries must be under `$HOME`\n\n; secret-like paths are skipped. Gitignored project-local files are not copied by default. Prefer committing project instructions such as `AGENTS.md`\n\n, `CLAUDE.md`\n\n, and `.claude/commands/`\n\nwhen they are meant to travel with the repo.\n\nModel credentials should go through Docker Sandboxes' secret manager or host-side auth flow, not be pasted into the VM.\n\nCommon setup:\n\n```\nsbx secret set -g anthropic          # Claude Code API key\nsbx secret set -g openai --oauth     # Codex OAuth\nsbx secret set -g openai             # Codex/OpenCode API key\n```\n\nAgent-specific notes:\n\n| Agent | Authentication |\n|---|---|\n| Claude Code | Run `code-airlock up` and use `/login` inside Claude, or store an Anthropic key with `sbx secret set -g anthropic` |\n| Codex | Use `sbx secret set -g openai --oauth` , `sbx secret set -g openai` , or export `OPENAI_API_KEY` before launch |\n| OpenCode | Store the provider keys you use, such as `openai` , `anthropic` , `google` , `xai` , `groq` , `aws` , or `openrouter` |\n\nSandboxes do not carry user-level config such as `~/.claude`\n\nor `~/.codex`\n\ninto the VM by design. Put project-level config in the repo if the agent needs it.\n\nCode Airlock does not need GitHub credentials for the normal fetch/diff/merge review loop.\n\nGive the sandbox GitHub access only if you want the agent to use `gh`\n\n, open pull requests, create issues, or push directly from inside the VM:\n\n```\necho \"$(gh auth token)\" | sbx secret set -g github\n```\n\nGlobal secrets apply when a sandbox is created. For an existing sandbox, either recreate it or scope the token to that sandbox:\n\n```\necho \"$(gh auth token)\" | sbx secret set sandbox-sbx-my-project github\n```\n\nIf you use SSH remotes, Docker Sandboxes can forward your host SSH agent when `SSH_AUTH_SOCK`\n\nis set. The private key stays on the host; sandboxed processes can request signatures but cannot read the key.\n\nOn first use, Code Airlock initializes Docker Sandboxes' global network policy to `balanced`\n\nif it has not been initialized yet.\n\nOverride that default:\n\n```\nGLOBAL_NETWORK_POLICY=deny-all code-airlock up\nGLOBAL_NETWORK_POLICY=allow-all code-airlock up\n```\n\nFor stricter runs, use:\n\n```\ncode-airlock lockdown\n```\n\nRun `lockdown`\n\nafter the sandbox exists. It sets Docker Sandboxes' global default to deny-all, then applies Code Airlock's allowlist to the named sandbox.\n\nUndo the global policy change with:\n\n```\ncode-airlock unlock\n```\n\n`unlock`\n\nruns `sbx policy reset`\n\n, which restores Docker Sandboxes' policy defaults.\n\nThe default allowlist covers Anthropic, OpenAI, GitHub, and npm:\n\n```\napi.anthropic.com,*.anthropic.com,api.openai.com,*.openai.com,github.com,*.github.com,codeload.github.com,objects.githubusercontent.com,registry.npmjs.org,*.npmjs.org\n```\n\nCustomize it with `sandbox.conf`\n\n:\n\n```\n# sandbox.conf\nAGENT=codex\nALLOW=api.openai.com,*.openai.com,github.com,*.github.com,registry.npmjs.org,*.npmjs.org\n```\n\nIf a download fails, inspect blocked hosts:\n\n```\ncode-airlock net\n```\n\nPass agent arguments after `--`\n\n.\n\nClaude Code:\n\n```\ncode-airlock up -- -p \"add pagination to the users endpoint and run the test suite\"\n```\n\nCodex:\n\n```\nAGENT=codex code-airlock up -- --dangerously-bypass-approvals-and-sandbox \"fix the build\"\n```\n\nOpenCode defaults to a TUI. Pass OpenCode's own flags after `--`\n\nwhen you need session-specific behavior.\n\nCopy `sandbox.conf.example`\n\nto `sandbox.conf`\n\nand edit:\n\n```\ncp sandbox.conf.example sandbox.conf\n```\n\nUseful settings:\n\n```\nSANDBOX_NAME=sbx-my-project\nAGENT=claude\nREPO_DIR=/absolute/path/to/repo\nGLOBAL_NETWORK_POLICY=balanced\nREVIEW_TOOL=vscode\nTMUX_SESSION=code-airlock-sbx-my-project\nTMUX_ATTACH=1\nSEED_CONFIG=0\nSEED_PATHS=$HOME/.codex/config.toml,$HOME/.claude/settings.json\nFETCH_SUBMODULES=1\nALLOW=api.anthropic.com,*.anthropic.com,github.com,*.github.com\n```\n\n`sandbox.conf`\n\nis git-ignored.\n\n| Command | What it does |\n|---|---|\n`up [-- agent-args]` |\nCreate and start the sandbox in clone mode with the selected agent |\n`run \"<task>\"` |\nStart the sandbox and hand the agent one task non-interactively |\n`setup` |\nGuided install of missing prerequisites; asks before running each step |\n`doctor` |\nCheck `sbx` , virtualization/KVM, git, daemon reachability, and login status |\n`status` |\nShow this repo's sandbox and tmux session status |\n`attach` |\nAttach to this repo's Code Airlock tmux session |\n`init` |\nCreate a starter `AGENTS.md` in the target repo |\n`shell` |\nOpen a shell inside the running sandbox |\n`fetch` |\nFetch the sandbox commits into your local repo, including initialized submodule commits |\n`diff [base]` |\nFetch, then show `base..sandbox-<name>/base` |\n`review [base]` |\nFetch, then open a visual Git difftool review |\n`merge [base]` |\nFetch, then merge the sandbox branch into `base` |\n`pr [base] [branch]` |\nFetch, push the sandbox branch to `origin` , and open a pull request |\n`completion [shell]` |\nPrint bash or zsh shell completion |\n`net` |\nShow allowed and blocked network hosts |\n`stop` |\nStop the sandbox but keep its VM and commits |\n`rm` |\nRemove the sandbox and repo tmux session after offering to fetch commits |\n`lockdown` |\nSet the global policy to deny-all and apply the allowlist to an existing sandbox |\n`unlock` |\nReset Docker Sandboxes policies with `sbx policy reset` |\n\nGlobal option:\n\n| Option | What it does |\n|---|---|\n`--agent <name>` |\nSelect the agent for this invocation (overrides `AGENT` ) |\n`--dry-run` |\nPrint commands instead of running them |\n`--tmux` |\nRun `up` inside a host-side tmux session and attach |\n`--tmux-detached` |\nRun `up` inside a detached host-side tmux session |\n`--seed-config` |\nCopy curated user-level agent config before starting |\n\n- The isolation boundary is the Docker Sandbox microVM, not the agent's own permission model.\n- Clone mode keeps your host repo mounted read-only.\n`lockdown`\n\nsets the default network policy to deny-all for all Docker Sandboxes. Revert with`code-airlock unlock`\n\n.- Keep the allowlist as narrow as the task allows. Allowed hosts remain possible egress paths.\n- Do not give the sandbox broad credentials unless the task truly requires them.\n`code-airlock rm`\n\ndeletes the sandbox clone. Fetch or push anything you want to keep first.\n\n```\n# bash: add to ~/.bashrc\nsource <(code-airlock completion bash)\n\n# zsh: add to ~/.zshrc\nsource <(code-airlock completion zsh)\n```\n\nHomebrew installs register the completions automatically.\n\n| Platform | Status |\n|---|---|\n| macOS on Apple Silicon | Supported |\n| macOS on Intel | Not supported (Docker Sandboxes requires Apple Silicon) |\n| Linux | Supported with KVM enabled (`lsmod | grep kvm` ) |\n| Windows 11 | Supported under WSL2 with Hypervisor Platform |\n| Remote servers | Supported over SSH; use `--tmux` so runs survive disconnects |\n\nRequired everywhere: Git and the Docker Sandboxes CLI (`sbx`\n\n). `code-airlock doctor`\n\nverifies all of this on the current machine.\n\nMIT. See [LICENSE](/Trivo25/code-airlock/blob/main/LICENSE).", "url": "https://wpnews.pro/news/show-hn-code-airlock-run-claude-code-and-codex-in-disposable-microvms", "canonical_source": "https://github.com/Trivo25/code-airlock", "published_at": "2026-07-11 10:16:50+00:00", "updated_at": "2026-07-11 10:35:03.477338+00:00", "lang": "en", "topics": ["ai-tools", "developer-tools", "ai-agents", "ai-safety", "ai-infrastructure"], "entities": ["Code Airlock", "Claude Code", "Codex", "OpenCode", "Docker Sandboxes", "Trivo25"], "alternates": {"html": "https://wpnews.pro/news/show-hn-code-airlock-run-claude-code-and-codex-in-disposable-microvms", "markdown": "https://wpnews.pro/news/show-hn-code-airlock-run-claude-code-and-codex-in-disposable-microvms.md", "text": "https://wpnews.pro/news/show-hn-code-airlock-run-claude-code-and-codex-in-disposable-microvms.txt", "jsonld": "https://wpnews.pro/news/show-hn-code-airlock-run-claude-code-and-codex-in-disposable-microvms.jsonld"}}