Sandboxing Claude Code using Multipass
Introduction
Claude Code ([CC]) is an AI agent capable of planning, coding, and debugging features by following instructions given in natural language.
Running CC as a regular development tool is risky, because what it does is effectively remote code execution (RCE). It comes with built-in safeguards, but if something goes wrong—because of a bug, a vulnerability, or simply because you are tired of reviewing its commands and accept something you should not—you will be lucky if you only lose some files. This is why it is important that it has access only to the files it actually needs.
Multipass is a virtualization tool that simplifies the management of virtual machines. It provides a CLI interface that you can control from scripts.
Running CC inside a Multipass sandbox is an easy way to limit risk and even run it with the -p or --dangerously-skip-permissions flags.
Configuring Multipass
Multipass supports cloud-init initialization scripts. I am using C# for programming, so your toolchain will probably be different. CC does not offer an official package distribution and will be installed later.
#cloud-init
packages:
- curl
- unzip
- git
- dotnet-sdk-8.0
users:
- name: gregor
groups: sudo, nogroup
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL
ssh_authorized_keys:
- <public-ssh-key-goes-here>
After installing Multipass, you can start the virtual machine by running:
multipass launch -n my-cc-sandbox --cloud-init ./cloud-init --disk 20G --memory 4G
On a Windows host, Multipass uses Hyper-V to manage virtual machines. The default Hyper-V network (“Default Switch”) provides each virtual machine with a NATed IP address, which allows the machine to access the internet. The biggest issue with this setup is that when the machine is restarted, its IP address changes. I work around this problem by giving the machine an entry in the local hosts file (C:\Windows\System32\drivers\etc\hosts) and then always referring to it by name.
# drivers/etc/hosts file
172.23.226.237 my-cc-sandbox
After the machine is started, you can connect to it via SSH:
ssh "gregor@my-cc-sandbox"
Configuring CC and Git
In addition to the cloud-init script, I have a script (setup.sh) that I run after creating the machine.
install_claude_code()
{
curl -fsSL https://claude.ai/install.sh | bash
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc && source ~/.bashrc
}
configure_git()
{
cat << EOF > .gitconfig
[user]
name = ...
email = ...
[core]
autocrlf = false
eol = lf
... other git configuration goes here
EOF
... additional GIT configuration stuff
}
Sharing code between host and sandbox
CC should only have access to the code it needs to perform its job. I still run Rider on the host, which I use for editing the code manually. To share the code between the host and the sandbox, I use Git.
# On the virtual machine: create a bare Git repository
mkdir -p my-git-repo.git
git -C my-git-repo.git init --bare
# On the host: add the virtual machine as a remote and push to it.
git remote add sandbox gregor@my-cc-sandbox:~/my-git-repo.git/
git push --all sandbox
# On the virtual machine: clone the bare Git repository
git clone my-git-repo.git
To synchronize changes back to the host, I ask CC to commit and push the changes. Then, on the host, I simply pull from the sandbox remote. The benefit of this setup is that the sandbox does not need access to any external resources.
Conclusion
The ideas described here can be wrapped into a couple of scripts and included in your project repository. Running CC in a sandbox then becomes almost as easy as running it locally, with the added benefit of not having to worry about what it might access or delete when it hallucinates its next solution.