Skip to content
| Marketplace
Sign in
Visual Studio Code>Linters>BoxEscape: Dev Container and Agent Sandbox Escape CheckerNew to Visual Studio Code? Get it now.
BoxEscape: Dev Container and Agent Sandbox Escape Checker

BoxEscape: Dev Container and Agent Sandbox Escape Checker

jaytank_dev

| (0) | Free
Finds the settings that hand your host to an AI coding agent running "safely" in a dev container or Docker sandbox: --privileged, a mounted docker.sock, host network or PID, CAP_SYS_ADMIN, seccomp=unconfined, ~/.ssh, ~/.aws or $HOME mounted in, forwarded SSH agents, a firewall script that never runs
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

BoxEscape: Dev Container and Agent Sandbox Escape Checker

You put the coding agent in a dev container so it can run with fewer prompts, maybe with --dangerously-skip-permissions. It is in a box, so it is safe. Then you look at what the box was built with:

{
  "name": "claude",
  "features": {
    "ghcr.io/anthropics/devcontainer-features/claude-code:1.0": {},
    "ghcr.io/devcontainers/features/docker-outside-of-docker:1": {}   // the host's docker.sock
  },
  "privileged": true,                                                   // "needed for docker"
  "runArgs": ["--network=host"],                                        // "needed for the dev server"
  "mounts": [
    "source=${localEnv:HOME}/.aws,target=/home/node/.aws,type=bind",    // "needed for the deploy script"
    "source=${localEnv:HOME}/.ssh,target=/home/node/.ssh,type=bind"     // "needed for git"
  ],
  "postStartCommand": "sudo /usr/local/bin/init-firewall.sh || true"   // and if it fails, nobody knows
}

Each line was added for a good reason, and together they hand the agent your host: a mounted Docker socket is root on the machine, privileged turns off every kernel protection, and your cloud and SSH keys are one prompt injection away from being sent somewhere.

BoxEscape reads your devcontainer.json, your Docker Compose services and the docker run lines in scripts that start an agent CLI, and shows every setting that lets the container reach the host. When the container runs an AI agent (Claude Code, Codex, Aider, OpenCode, OpenHands, Cline, Cursor Agent, Gemini CLI), the findings that expose secrets or the host are errors.

What you see

  • Problems and squiggles on the exact setting, with a message that says what it gives the container, and why the container counts as an agent container (It runs an AI agent (feature claude-code) ...).
  • Quick Fixes (lightbulb): remove privileged, remove a dangerous capAdd / cap_add entry or --cap-add argument, remove a securityOpt entry, remove the docker.sock mount or the docker-outside-of-docker Feature, make a mount read-only (,readonly for mount strings, :ro for -v and Compose volumes).
  • Activity bar: a BoxEscape icon opens the Container escape checks view. Findings are grouped by file, and each row names the setting, what it brings in and which container: mounts: ~/.aws into the "claude" container, runArgs --network: host network shared with the "claude" container, privileged: true runs the "agent" service privileged. Click a row to jump to it, or use the inline lightbulb button to apply its Quick Fix. A badge on the icon shows the number of findings.
  • Status bar: BoxEscape: N. Click it to open the view.

Open files are checked as you type. The rest of the workspace is scanned in the background.

Rules

ID Rule Default Examples Quick Fix
BE001 Privileged container Error "privileged": true, runArgs --privileged, the docker-in-docker Feature, Compose privileged: true, docker run --privileged Remove it
BE002 Host Docker socket shared Warning, error in an agent container /var/run/docker.sock (also /run/docker.sock, Docker Desktop, rootless, Podman and containerd sockets, /var/run itself) in mounts, -v, Compose volumes; the docker-outside-of-docker Feature; docker run --use-api-socket Remove the mount or the Feature
BE003 Host namespace shared Warning --network=host, --pid=host, --ipc=host, --userns=host, --cgroupns=host; Compose network_mode: host, pid, ipc, userns_mode, cgroup -
BE004 Dangerous capability added Error for ALL, SYS_ADMIN, SYS_MODULE, SYS_RAWIO, DAC_READ_SEARCH; warning for NET_ADMIN, BPF, PERFMON, SYS_TIME capAdd, --cap-add, Compose cap_add. NET_ADMIN is not reported when the container runs an egress firewall script (the documented reason for it) Remove the entry
BE005 Confinement turned off Error; warning for label=disable seccomp=unconfined, apparmor=unconfined, systempaths=unconfined in securityOpt, --security-opt, Compose security_opt Remove the entry (devcontainer.json, block lists)
BE006 Host credentials or system path mounted Warning, error in an agent container; one step lower when the mount is read-only ~/.ssh, ~/.aws, ~/.azure, ~/.config/gcloud, ~/.kube, ~/.docker, ~/.gnupg, ~/.config/gh, ~/.git-credentials, ~/.netrc, ~/.npmrc, ~/.pypirc and others, your whole $HOME, /, /etc, /proc, /sys, /home ... in every home form: ${localEnv:HOME}, ${localEnv:USERPROFILE}, $HOME, ${HOME}, ~, /home/<you>, /Users/<you>, C:\Users\<you> Make the mount read-only
BE007 Workspace parent mounted Warning ${localWorkspaceFolder}/.., Compose ../..:/workspaces in .devcontainer/ (resolved against the Compose file), $(pwd)/.. -
BE008 SSH or GPG agent forwarded Warning, error in an agent container ${localEnv:SSH_AUTH_SOCK}, $SSH_AUTH_SOCK, Docker Desktop's /run/host-services/ssh-auth.sock, S.gpg-agent sockets mounted in Remove the mount
BE009 Host device passed through Warning --device=/dev/sda, /dev/mem, /dev/nvme0n1, Compose devices, device_cgroup_rules: ['a *:* rwm']. GPUs (/dev/dri, /dev/nvidia*), /dev/fuse, /dev/net/tun, /dev/kvm, sound, video and USB serial devices are not reported -
BE010 Agent firewall not effective Information A lifecycle command runs init-firewall.sh (or any *firewall*.sh) that is not in the repository; its failure is ignored (\|\| true); it runs without the NET_ADMIN capability iptables needs; or a firewall script sits next to an agent's devcontainer.json and nothing runs it -
BE011 Agent runs as root Warning remoteUser / containerUser root in an agent container, Compose user: root / "0:0", docker run -u 0 -

Set any rule to another severity or off with boxEscape.rules.

When is a container an agent container?

When BoxEscape sees one of these, the message says which:

  • devcontainer.json: its name (claude, Codex sandbox, ai-agent ...), a Feature (ghcr.io/anthropics/devcontainer-features/claude-code, codex, aider, gemini-cli, opencode), an extension in customizations.vscode.extensions (anthropic.claude-code, openai.chatgpt, Cline, Roo Code, Kilo Code), a lifecycle command that installs or runs an agent CLI (npm i -g @openai/codex, curl -fsSL https://claude.ai/install.sh | bash, aider ...), containerEnv like CLAUDE_CONFIG_DIR or CODEX_HOME, or a Dockerfile (build.dockerfile) that installs one.
  • Docker Compose: the service named in an agent devcontainer.json (dockerComposeFile + service), or a service whose name, container_name, image, command / entrypoint, environment or build Dockerfile shows an agent.
  • Scripts (*.sh, *.bash): only docker run / podman run / nerdctl run lines that start an agent (... image claude -p, an agent image, --name codex-sandbox, -e CLAUDE_CODE_...) are checked. Every other docker run in your scripts is left alone.
  • Your own agent tools: add a pattern to boxEscape.extraAgentPatterns.

What it leaves alone

  • SYS_PTRACE (the documented capability for debuggers) and NET_RAW (in Docker's default set).
  • Named volumes (source=claude-code-config,target=/home/node/.claude,type=volume), the workspace itself, and folders inside your home that are not credential folders (~/projects/app).
  • NET_ADMIN / NET_RAW next to an egress firewall that runs at start, as in the Claude Code reference container, which BoxEscape reports nothing for.
  • Comments, heredoc bodies and quoted text in scripts.

The checks follow the devcontainer.json reference, the Claude Code dev container docs ("avoid mounting host secrets such as ~/.ssh or cloud credential files", the reference firewall and its capabilities) and Docker Engine security ("only trusted users should be allowed to control your Docker daemon").

Settings

Setting Default Description
boxEscape.enabled true Turn all checks on or off.
boxEscape.rules {} Severity per rule (error, warning, information, hint) or off, e.g. { "BE007": "off" }. Rules not set here use the per-finding defaults above.
boxEscape.extraAgentPatterns [] Extra regular expressions (case-insensitive, up to 200 characters each, 20 patterns) that mark a container as an agent container.
boxEscape.checkScripts true Also check docker run lines in shell scripts that start an agent CLI.
boxEscape.maxFiles 2000 Maximum number of files scanned. Files open in an editor are always checked. Files over 1 MB are skipped.
boxEscape.exclude node_modules, .git, dist, build, out, vendor, venv, .venv, __pycache__, coverage, site-packages Glob patterns that are never scanned. node_modules, .git, vendor, venv and .venv are always excluded.

Settings apply immediately, without a reload.

Commands

  • BoxEscape: Rescan Workspace (also the refresh button in the view title)
  • BoxEscape: Show Container Escape Checks
  • BoxEscape: Open Settings (gear button in the view title)
  • Apply Quick Fix (inline button on each fixable row)

Files checked

devcontainer.json and .devcontainer.json anywhere in the workspace, Compose files (compose.yaml, docker-compose.yml, docker-compose.dev.yml and other *compose*.yml / *.yaml names, plus any file a devcontainer.json names in dockerComposeFile), and *.sh / *.bash scripts. Dockerfiles are read only to see whether they install an agent or run a firewall script.

Privacy and safety

  • No network, no telemetry. Nothing leaves your machine.
  • BoxEscape only reads files inside the workspace. Symlinks that lead outside are ignored, and files over 1 MB are skipped. It never runs Docker or any other process.
  • It works in untrusted workspaces. There, all boxEscape.* settings (including enabled, rules and exclude) are taken only from your user settings, never from the repository.

Limitations

  • BoxEscape reads configuration, not the running container. Settings added by a Feature's own metadata are known only for the docker-in-docker and docker-outside-of-docker Features, and the base image's default user is not known, so BE011 needs an explicit root.
  • Read-only mounts are still reported (one severity lower): a read-only ~/.ssh can not be changed, but the keys in it can still be read and sent out. Removing the mount and passing a short-lived, repository-scoped token is the real fix.
  • VS Code's Dev Containers extension forwards your SSH agent and reuses your git credential helper on its own when they are set up on the host. That is not visible in devcontainer.json, so BE008 only reports agent sockets that are mounted explicitly.
  • Flags hidden in shell variables (docker run $FLAGS ...) and Compose extends from other files are not followed. Compose ${VAR} values are not substituted, except the home forms above.

License

MIT - included with the extension.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft