Running Claude Code dangerously (safely)
Background
I’ve been using Claude Code more and more recently. At some point I realized that rather than do something else until it finishes, I would constantly check on it to see if it was asking for yet another permission, which felt like it was missing the point of having an agent do stuff. So I wanted to use Claude Code with the --dangerously-skip-permissions flag.
If you haven’t used it, this flag does exactly what it says: it lets Claude Code do whatever it wants without asking permission first. No more “May I install this package?”, “Should I modify this config?”, “Can I delete these files?”
It just… does it.
Which is great for flow since I don’t have to worry that it stopped doing stuff just to ask a permission question.
But also, you know, dangerous.
I like my filesystem intact, so the obvious solution is to not run this thing directly on my OS account.
What I considered
Docker
First instinct: throw it in a Docker container. Containers are for isolation, right?
Except I want Claude to be able to build Docker images. And run containers. And maybe orchestrate some stuff.
So now you need Docker-in-Docker, which means --privileged mode, which defeats the entire purpose of sandboxing. That means trading “Claude might mess up my filesystem” for “Claude has root-level access to my container runtime.”
Not great.
There’s also the nested networking weirdness, volume mounting permissions that make you question your life choices, and the general feeling that you’re fighting the tool instead of using it.
Other options
I also briefly considered:
- #yolo run it bare metal: no, no and no
- sandbox-runtime: more of an ACL approach, I want Claude to be able to do anything, because it doesn’t have access to anything except the code
- firejail or similar: same problem as Docker-in-Docker
- manual VM setup: works but tedious, not reproducible
- cloud VM: costs money, has latency, need to upload my code somewhere
Vagrant
Then I remembered about a project that I’ve used before Docker became all the rage: Vagrant.
If you weren’t around back then, Vagrant gives you proper VM isolation with a reproducible config file. It’s basically infrastructure as code for your local dev environment.
You get:
- full VM isolation (no shared kernel)
- easy to nuke and rebuild
- shared folders that make it feel local enough
- no Docker-in-Docker nonsense
I hadn’t used VirtualBox in years since Docker containers covered all requirements until now, so I grabbed the latest version (7.2.4) and got started.
First vagrant up and… the VM is pegging my CPU at 100%+ while completely idle.
I spent an hour turning off various VM features, tweaking settings, googling asking LLMs random combinations of “virtualbox high cpu idle”, you know, the usual.
Eventually I found this GitHub issue. VirtualBox 7.2.4 shipped with a regression that causes high CPU usage on idle guests. What are the odds.
Vagrantfile
Here’s what my simple Vagrantfile looks like:
vm_name = File.basename(Dir.getwd)
Vagrant.configure("2") do |config|
config.vm.box = "bento/ubuntu-24.04"
#config.vm.network "forwarded_port", guest: 3000, host: 3000, auto_correct: true
config.vm.synced_folder ".", "/agent-workspace", type: "virtualbox"
config.vm.provider "virtualbox" do |vb|
vb.memory = "4096"
vb.cpus = 2
vb.gui = false
vb.name = vm_name
vb.customize ["modifyvm", :id, "--audio", "none"]
vb.customize ["modifyvm", :id, "--usb", "off"]
end
config.vm.provision "shell", inline: <<-SHELL
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y docker.io nodejs npm git unzip
npm install -g @anthropic-ai/claude-code --no-audit
usermod -aG docker vagrant
chown -R vagrant:vagrant /agent-workspace
SHELL
end
How it works in practice
Now I just run:
cd ~/my-project
vagrant up
vagrant ssh
claude-code --dangerously-skip-permissions
# Let Claude do its thing
exit
vagrant suspend
First boot takes a few minutes to provision everything, and you need to sign in to Claude, but after that, vagrant up is quite fast.
Supercharged Claude
So, what can Claude do with these newfound powers?
Since it’s running in a VM, I also gave it sudo access and instructed it that it has the power to do anything: install system packages, modify configs, create files, run Docker containers, whatever.
It has:
- manually started a webapp API and inspected it with curl requests
- installed a browser and manually inspected the app, then built end-to-end tests based on that
- setup a postgres database, ran test sql, tested that db migrations work, etc
- built and ran Docker images
All things I’d be nervous about on my host machine, especially with the “just do it” flag enabled.
And now I feel Claude is much more effective since it has the extra context, it’s not relying on me to run the command, return the output or error message, and then iterate. It just does it by itself.
Performance
Claude Code isn’t exactly a resource hog, and the VM has plenty of headroom. The shared folder sync works fine, no lag or weirdness when files change. This is under Linux with VirtualBox, YMMV for other platforms.
Safety
What you’re protecting against:
- accidental filesystem damage
- aggressive package installations
- configuration changes you didn’t catch
- general “oops I didn’t mean Claude to do that”
What you’re NOT protecting against:
- deleting the actual project, since the file sync is two-way
- a malicious AI trying to escape the VM (VM escape vulnerabilities exist, but they’re rare and require deliberate exploitation)
- network-level attacks/oopsies from the VM
- data exfiltration: the VM still has internet access, but besides the code there shouldn’t really be any data to exfiltrate
Threat model: I don’t trust myself to always catch what the agent is doing when I’m in the zone and just want stuff to work. This setup is about preventing accidents, not sophisticated attacks.
Conclusion
This took a bit to get right, mostly because of the VirtualBox CPU bug. But now it’s frictionless. I can let Claude Code do whatever it wants without fear, and if something goes sideways, I just nuke the VM and start fresh.
The Vagrantfile is short and reproducible. Drop it in any project directory, vagrant up, and you’re sandboxed.
If you’re using Claude Code with the dangerous flag, I’d recommend something like this. Even if you’re careful about what you approve, it only takes one moment to mess things up.