Running AI agents safely in a microVM using docker sandbox The article describes how to safely run AI coding agents like Claude Code in "dangerous" modeβ€”which bypasses permission prompts for improved productivityβ€”by using Docker Sandboxes. These sandboxes provide security through isolated microVMs with their own kernels and networks, preventing agents from accessing or damaging the host system. The author explains that while bypassing permissions is risky, running agents inside a Docker sandbox allows them to operate freely without constant user supervision. In this post I describe one way to run coding agents locally safely while still using "YOLO" or "dangerous" mode, by using Docker Sandboxes https://docs.docker.com/ai/sandboxes/ . Powerful agents, but they need a lot of hand holding powerful-agents-but-they-need-a-lot-of-hand-holding It's pretty safe to assume that if you're reading this, you're probably using some sort of coding agent these days, whether that's Claude Code, Codex, Copilot, or something else. I have a whole bunch of ethical, environmental, and sustainability concerns about the technology, but the fact is that in 2026, they've got so much better than they were even 6 months ago. I am massivelyconflicted about the role of AI in software engineering let alone other areas of life , but I'm not going to address that in this post. For better or worse, it feels like working with coding agents is practically becoming a job requirement, so learning how to do it safely seems important.. I've been very impressed with how effective Claude Code can be at adding new features, maintenance, and problem solving, but there's one thing that's infuriating… the dreaded tool-call permissions. The real problem is that Claude asks this for endless things. Want to use grep ? Confirm permission. Want to use sed ? Confirm permission. Want to use cd because Claude Code doesn't understand Windows https://github.com/anthropics/claude-code/issues/30524 ? Confirm permission. This is an absolute killer for productivity. Using the tools like this becomes exhausting, constantly switching between terminal windows to find the agent that's managed to run into a wall again πŸ™„ In this post I'm focusing on Claude Code as that's what I have the most experience with, but everything pretty much works the same for other agents as I understand it too. Live dangerously, if you dare live-dangerously-if-you-dare Of course, there is a solution, but it's not for the feint-hearted. Claude Code has the flag --allow-dangerously-skip-permissions , which adds a "bypass permissions" mode https://code.claude.com/docs/en/permission-modes switch-permission-modes to the standard "plan" and "accept edit" modes. This flag means "bypass permissions" mode is available, but it doesn't startin that mode. If you want to start in that mode, you can use --permission-mode bypassPermissions or --dangerously-skip-permissions instead. If you start claude code using: claude --allow-dangerously-skip-permissions Then you'll get a warning: and you can select bypass permissions on demand by cycling through modes with Shift + Tab The trouble is, then you won't get any permission tool requests. If Claude decides to run something stupid that deletes your User folder then sorry, that's you hosed. It's right there in the warning…this is dangerousπŸ˜… And yet… The experience in bypass permissions mode is just so much better when you want the agent to just go and do something or even if you just want it to create a plan . It doesn't bother you about every little thing, it just does the task . That's a hard experience to give up, but there are options that can get you pretty close to this, safely . Live safely, in a sandbox live-safely-in-a-sandbox Docker recently released Docker Sandboxes https://docs.docker.com/ai/sandboxes/ . It might surprise you that this actually isn't built on containers, but rather on isolated microVM sandboxes. This has some security advantages https://docs.docker.com/ai/sandboxes/security/ : - Unlike containers, which share the host kernel, each sandbox has its own kernel - The microVM runs a separate docker engine inside so you can build and run containers without having to mount your host docker socket - The network in the microVM is isolated from the host. A network proxy runs on the host side, intercepting traffic, blocking access to the host's localhost, and automatically injecting authentication headers so that the sandbox doesn't have access to them . With all this isolation, the idea is that you can just let your agents run amok, without having to babysit them. Sounds ideal, right? Docker sandboxes are experimental. Until recently, it was shipping with Docker Desktop and you ran commands like docker sandbox run . However, they recently switched to shipping a dedicated sbx tool that doesn't require docker desktop. For the rest of this post I'll discuss the basics of getting started with sandboxes, and my brief experience with them. Getting started with getting-started-with-sbx-sandbox sbx sandbox sbx sandboxDue to the experimental nature of the sbx tool and Docker Sandboxes in general, this post is going to be relatively light on details and will focus on the basics, as I expect it will go out of date rapidly. Instead, I recommend you check the docs https://docs.docker.com/ai/sandboxes/usage/ for more advanced usages. Installing the installing-the-sbx-tool sbx tool sbx toolTo get started, you'll first need to install the sbx tool. Only macOS arm64 and Windows x86 64, Windows 11 are currently supported, and I'm going to provide the instructions for Windows seeing as that's what I'm using. First, you'll need to make sure you have the HypervisorPlatform feature enabled. This is different but related to the full Hyper-V feature. It's used by WSL2, so it's very likely you already have this enabled anyway, but just in case, run the following in an administrator PowerShell prompt: Enable-WindowsOptionalFeature -Online -FeatureName HypervisorPlatform -All Next, install the sbx tool using WinGet https://learn.microsoft.com/en-us/windows/package-manager/winget/ , or by downloading the MSI from the Github releases page https://github.com/docker/sbx-releases/releases : winget install -h Docker.sbx You'll need to open a new terminal window to make sure the tool is available. Signing in and configuring the defaults signing-in-and-configuring-the-defaults Once you've installed and opened a new terminal window , you have to sign-in to use docker sandboxes, so start by running sbx login or just sbx , it'll do the same thing : ❯ sbx You are not authenticated to Docker. Starting the sign-in flow... Your one-time device confirmation code is: FXDG-FKTF Open this URL to sign in: https://login.docker.com/activate?user code=FXDG-FKTF By logging in, you agree to our Subscription Service Agreement. For more details, see https://www.docker.com/legal/docker-subscription-service-agreement/ Waiting for authentication... This pops up a login window, where you first confirm, and then login to docker: You're then provided with a choice of how to configure your network: Signed in as andrewlock. Daemon started PID: 52268, socket: \\.\pipe\docker kaname sandboxd Logs: C:\Users\sock\AppData\Local\DockerSandboxes\sandboxes\state\sandboxd\daemon.log Select a default network policy for your sandboxes: 1. Open β€” All network traffic allowed, no restrictions. 2. Balanced β€” Default deny, with common dev sites allowed. 3. Locked Down β€” All network traffic blocked unless you allow it. Use ↑/↓ or 1–3 to navigate, Enter to confirm, Esc to cancel. The descriptions here are relatively self-evident, and it depends on how locked down you want your sandbox to be. All communication from the sandbox goes through a proxy, so it's really this proxy you're configuring. The network policies are a new feature since I started working with the sandboxes, so I haven't experimented with these myself yet. I tried out Balanced, and used sbx policy ls to describe the policies, and it configured the following as allowed domains; all other network requests will be blocked: | Name | Resources | |---|---| | default ai services | .chatgpt.com:443 , .oaistatic.com:443 , .oaiusercontent.com:443 , .openai.com:443 , api.anthropic.com:443 , api.perplexity.ai:443 , cdn.openaimerge.com:443 , chatgpt.com:443 , gemini.google.com:443 , generativelanguage.googleapis.com:443 , models.dev:443 , nanoclaw.dev:443 , platform.claude.com:443 , play.googleapis.com:443 , statsig.anthropic.com:443 | | default package managers | .bun.sh:443 , .gradle.org:443 , .packagist.org:443 , .yarnpkg.com:443 , apache.org:443 , astral.sh:443 , bootstrap.pypa.io:443 , bun.sh:443 , cocoapods.org:443 , cpan.org:443 , crates.io:443 , dot.net:443 , dotnet.microsoft.com:443 , eclipse.org:443 , files.pythonhosted.org:443 , golang.org:443 , goproxy.io:443 , gradle.org:443 , haskell.org:443 , hex.pm:443 , index.crates.io:443 , java.com:443 , java.net:443 , maven.org:443 , metacpan.org:443 , nodejs.org:443 , nodesource.com:443 , npm.duckdb.org:443 , npmjs.com:443 , npmjs.org:443 , nuget.org:443 , packagist.com:443 , packagist.org:443 , pkg.go.dev:443 , proxy.golang.org:443 , pub.dev:443 , pypa.io:443 , pypi.org:443 , pypi.python.org:443 , pythonhosted.org:443 , registry.npmjs.org:443 , repo.maven.apache.org:443 , ruby-lang.org:443 , rubygems.org:443 , rubyonrails.org:443 , rustup.rs:443 , rvm.io:443 , sh.rustup.rs:443 , spring.io:443 , static.crates.io:443 , static.rust-lang.org:443 , sum.golang.org:443 , swift.org:443 , tuf-repo-cdn.sigstore.dev:443 , yarnpkg.com:443 , ziglang.org:443 | | default code and containers | .business.githubcopilot.com:443 , .docker.com:443 , .docker.io:443 , .gcr.io:443 , .github.com:443 , .githubusercontent.com:443 , .gitlab.com:443 , .production.cloudflare.docker.com:443 , bitbucket.org:443 , dhi.io:443 , docker-images-prod.6aa30f8b08e16409b46e0173d6de2f56.r2.cloudflarestorage.com:443 , docker.com:443 , docker.io:443 , gcr.io:443 , ghcr.io:443 , github.com:443 , gitlab.com:443 , k8s.io:443 , launchpad.net:443 , mcr.microsoft.com:443 , ppa.launchpad.net:443 , production.cloudflare.docker.com:443 , public.ecr.aws:443 , quay.io:443 , registry.k8s.io:443 , sourceforge.net:443 | | default cloud infrastructure | .amazonaws.com:443 , .googleapis.com:443 , .googleusercontent.com:443 , .gstatic.com:443 , .gvt1.com:443 , .public.blob.vercel-storage.com:443 , .visualstudio.com:443 , apis.google.com:443 , app.daytona.io:443 , azure.com:443 , binaries.prisma.sh:443 , challenges.cloudflare.com:443 , clerk.com:443 , csp.withgoogle.com:443 , dev.azure.com:443 , dl.google.com:443 , fastly.com:443 , figma.com:443 , hashicorp.com:443 , jsdelivr.net:443 , json-schema.org:443 , json.schemastore.org:443 , login.microsoftonline.com:443 , mise-versions.jdx.dev:443 , mise.run:443 , packages.microsoft.com:443 , play.google.com:443 , playwright.azureedge.net:443 , supabase.com:443 , unpkg.com:443 , vercel.com:443 , visualstudio.com:443 , www.google.com:443 | | default os packages | .debian.org:443 , alpinelinux.org:443 , apt.llvm.org:443 , archive.ubuntu.com:443 , archlinux.org:443 , centos.org:443 , debian.org:443 , dl-cdn.alpinelinux.org:443 , fedoraproject.org:443 , packagecloud.io:443 , ports.ubuntu.com:443 , ports.ubuntu.com:80 , security.ubuntu.com:443 , ubuntu.com:443 | As you can see, this includes pretty much everything you might need for building applications, but it's notably missing things like documentation sites, so if your agent needs to go out to Microsoft learn for example , it's going to be stuck. I think that could be a big gap in the balanced mode, so I switched to "open" mode instead by running sbx policy reset and choosing again. Creating a sandbox creating-a-sandbox Once you've chosen your network policy, you can create your first sandbox. Navigate to your project folder, and run sbx run claude : cd .\NetEscapades.EnumGenerators sbx run claude This downloads a docker image for the selected agent, and creates a sandbox named after the current working directory. Once downloaded, sbx uses the image to spin up a microVM and runs your agent of choice in YOLO/dangerously skip permissions mode: Creating new sandbox 'claude-NetEscapades.EnumGenerators'... aeacf85cf4c8: Download complete 4f33085e2ac1: Download complete 6b4ac13f7bd1: Download complete Digest: sha256:aeacf85cf4c8e40f5d1a3709ed7f2a7f466f78787e56780ec321f0db6bc1a53a Status: Downloaded newer image for docker/sandbox-templates:claude-code βœ“ Created sandbox 'claude-NetEscapades.EnumGenerators' Workspace: D:\repos\oss\NetEscapades.EnumGenerators direct mount Agent: claude To connect to this sandbox, run: sbx run claude-NetEscapades.EnumGenerators Starting claude agent in sandbox 'claude-NetEscapades.EnumGenerators'... Workspace: D:\repos\oss\NetEscapades.EnumGenerators β–β–›β–ˆβ–ˆβ–ˆβ–œβ–Œ Claude Code v2.1.90 β–β–œβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–›β–˜ Sonnet 4.6 Β· API Usage Billing β–˜β–˜ ▝▝ /d/repos/oss/NetEscapades.EnumGenerators ↑ Opus now defaults to 1M context Β· 5x more room, same pricing ─────────────────────────────────────────────────────────────────────────────────────────── ❯ ─────────────────────────────────────────────────────────────────────────────────────────── ⏡⏡ bypass permissions on shift+tab to cycle And you're off to the races You can hack away and know that the sandbox only has access to your working directory, so yes, it could delete your git repo and there are ways to avoid that too , but that's basically the extent of the damage it can do. Docker sandboxes currently have support for Claude Code, Codex, Copilot, Gemini, Kiro, OpenCode, and Docker Agent. You can now set Claude to work, and it runs in --dangerously-skip-permissions mode, without needing to prompt you everytime it needs to use a tool. So at this point, you probably need to review and push/reject those changes. So it's worth thinking about how git works with sbx . Committing changes to a git repository committing-changes-to-a-git-repository There's basically 2 ways you can use sbx sandboxes: - Direct mode - Branch mode In direct mode , the agent just edits files in your working directory, and commits directly to the git repository in that directory. This is the easiest to use and understand, but be aware that it has access to the whole git history, so technically the agent could end up breaking your git repo. I've never seen it, but it's important to be aware it could happenπŸ˜… In branch mode , the sbx sandbox creates a git worktree /working-on-two-git-branches-at-once-with-git-worktree/ in a .sbx/ sub-folder in your root directory, and starts the agent in that sub-folder. The agent still has access to the root directory, but it means you can continue to work in the "main" working directory, or you could start additional agents working in other worktrees. To start a sandbox in branch mode, pass the --branch flag. For example: agent creates a worktree at .sbx/