Put the Agent in a Box: Running Claude Code in a Container
TL;DR — Key Takeaways
-
Permission fatigue is a security risk. Repeated approval prompts become routine, leaving powerful AI coding agents with access to sensitive files, credentials and systems.
-
Containers put boundaries around autonomous coding. Restricted mounts, non-root execution, scoped credentials and controlled network access reduce an agent’s potential damage.
-
Sandboxing isn’t a silver bullet. Shared workspaces, allowed network destinations and host-kernel vulnerabilities still require careful security controls and oversight.
AI coding agents have moved well past autocomplete. A tool such as Claude Code reads your repository, runs shell commands, installs packages and edits files, often in a loop with little human input between steps. That is useful. It also means a process steered by a language model has the same reach on your laptop that you do: Your SSH keys, your cloud credentials and every other repository you have cloned.
Most teams manage this with permission prompts. The agent asks and the engineer clicks approve. By the 40th prompt of the afternoon, approval is a reflex and the prompt has stopped being a control. A container offers a better deal. You decide once, in a file your team can review, what the agent can see and reach, and then you stop negotiating command by command.
What the Agent Needs, and What it Doesn’t
Start with what the agent needs to do useful work: The project source, the language toolchain, a package registry, a git remote and an endpoint for model inference. That is a short list.
Now look at what a typical developer machine offers it: Dotfiles, long-lived tokens in ~/.aws or ~/.kube, a Docker socket and a VPN into internal networks. None of that is needed to fix a failing unit test. The gap between those two lists is your exposure if the agent misreads an instruction, follows a malicious comment planted in a dependency or runs the wrong rm command.
Containerizing the agent is how you close that gap.
Building the Box
Four decisions cover most of the work.
Image: Build a small image with your toolchain and the CLI pinned to a specific version, and turn off self-updates so every engineer and every pipeline gets the same binary.
FROM node:22-bookworm-slim
RUN apt-get update && apt-get install -y –no-install-recommends \ git ripgrep ca-certificates \
&& rm -rf /var/lib/apt/lists/* ARG CLAUDE_CODE_VERSION
RUN npm install -g @anthropic-ai/claude-code@${CLAUDE_CODE_VERSION} ENV DISABLE_AUTOUPDATER=1 \
CLAUDE_CONFIG_DIR=/home/node/.claude USER node
WORKDIR /workspace
Run as a non-root user. Claude Code refuses to start in its no-prompt mode as root, and that default is worth keeping.
Mounts: Mount the project and nothing else. Keep the agent’s login state and settings in a named volume rather than a bind mount of your home directory. Do not mount ~/.ssh, cloud credential files or the Docker socket. Access to the Docker socket is effectively root on the host.
docker run –rm -it \
–cap-drop ALL –security-opt no-new-privileges \
–network agent-internal \
-e HTTPS_PROXY=http://egress-proxy:3128 \
-e ANTHROPIC_API_KEY \
-v “$PWD”:/workspace \
-v claude-config:/home/node/.claude \ agent-box claude
Credentials: Pass a scoped API key or short-lived token as an environment variable. If the agent needs to push, give it a repository-scoped token instead of your personal credentials.
Egress: This is the control people skip, and it matters most. Deny outbound traffic by default and allow only the inference endpoint, your package registry and your git host. There are two common approaches. The reference dev container in the Claude Code repository runs an iptables script at startup that builds an allowlist and rejects everything else, which requires granting the container the NET_ADMIN and NET_RAW capabilities. The alternative, shown above, is to attach the agent to an internal Docker network with no route out and place a filtering forward proxy on that network as its only exit. Claude Code honors HTTPS_PROXY, so the agent container needs no extra capabilities and the allowlist lives in a component the agent cannot touch.
If your team already uses dev containers, the same decisions map directly onto devcontainer.json.
What You Get
A Bounded Failure: When the agent gets something wrong, the damage stops at the project directory and the allowlisted hosts. Rebuilding the container resets everything else.
Unattended Runs Become Reasonable: Inside a boundary you trust, you can relax permission prompts and let the agent work through a long task. The Claude Code documentation itself says the no-prompt mode belongs inside a container, a VM or an equivalent sandbox.
Reproducibility: The image pins the toolchain and the agent version. When a teammate reports that the agent behaved differently on their machine, the environment is no longer a suspect.
Faster Onboarding: A new engineer pulls one image and gets the same setup as everyone else, including organization policy placed in the managed settings file at /etc/claude-code/managed-settings.json.
The Same box in CI: The image that runs on laptops runs in a pipeline too. Headless mode takes a prompt on the command line and can return JSON:
claude –bare -p “Run the unit tests and fix any failures” \
–permission-mode dontAsk \
–allowedTools “Read,Edit,Bash(npm test *)” \
–output-format json
The –bare flag skips hooks, plugins and MCP servers defined in the checkout, which matters when the pipeline builds branches nobody has reviewed yet.
What the Box Doesn’t Solve
A container is a boundary, not a guarantee, and its edges are worth stating plainly.
Anything inside can leave through an allowed door. If the agent can read a token and reach an allowlisted host, that token can leave. Keep the contents of the container minimal and prefer short-lived credentials.
The workspace is shared with the host. Edits land on your disk, including files such as .git/hooks and .git/config that your host git will run or obey on the next commit. After an unattended run, check them before you use git outside the container.
Containers share the host kernel. For a repository you do not trust, use a virtual machine or microVM.
Policy in the repository is editable. Anyone with write access can change a Dockerfile that bakes in managed settings. Rules that must hold belong in device management or server-side policy.
The model still sees what the agent reads. Isolation limits reach, not disclosure. Files the agent opens go to the inference provider wherever the agent runs.
The friction is real. Login state has to survive rebuilds; the allowlist needs upkeep as tools add endpoints and bind mounts can be slow on macOS and Windows.
Closing
Containers became standard less because they made software safer and more. After all, they made environments explicit. Agents benefit from the same discipline. Write down what the agent needs, give it exactly that and let the boundary do the work that permission prompts were never going to do well.
Frequently Asked Questions
Why should AI coding agents run inside Docker containers?
Docker containers provide an isolated execution environment that limits an AI agent's access to host files, credentials and system resources. This helps reduce the impact of malicious instructions, accidental commands and unintended agent behavior.
How can developers secure Claude Code inside a container?
Developers can run Claude Code as a non-root user, mount only the required project directory, remove unnecessary Linux capabilities, restrict outbound network access and provide scoped credentials. Pinning tool versions and maintaining centrally managed security policies can further improve control.
Are Docker containers sufficient to secure autonomous AI coding agents?
No. Containers reduce an agent's reach but do not eliminate risks such as data exfiltration through permitted connections, modification of shared repository files or host-kernel vulnerabilities. Higher-risk workloads may require virtual machines or microVMs, along with additional credential and network protections.


