Claude Code Isolation and Burner Workflow 260211: Difference between revisions
Justinaquino (talk | contribs) |
Justinaquino (talk | contribs) Remove BoxBuddy; add True Filesystem Isolation section with isolated distrobox commands |
||
| Line 14: | Line 14: | ||
* A Linux host (Fedora, Ubuntu, Arch, etc.) | * A Linux host (Fedora, Ubuntu, Arch, etc.) | ||
* [https://github.com/89luca89/distrobox Distrobox] installed on the host | * [https://github.com/89luca89/distrobox Distrobox] installed on the host | ||
* A Claude Code account and API access | * A Claude Code account and API access | ||
== Step 1: Install Distrobox | == Step 1: Install Distrobox on the Host == | ||
Install distrobox on your host system: | Install distrobox on your host system: | ||
| Line 24: | Line 23: | ||
sudo dnf install distrobox # Fedora | sudo dnf install distrobox # Fedora | ||
yay -S distrobox # Arch (AUR) | yay -S distrobox # Arch (AUR) | ||
== Step 2: Create a Distrobox Container == | == Step 2: Create a Distrobox Container == | ||
| Line 38: | Line 33: | ||
distrobox enter claude-container | distrobox enter claude-container | ||
== Step 3: Install Claude Code Inside the Container == | == Step 3: Install Claude Code Inside the Container == | ||
| Line 138: | Line 131: | ||
Claude Code will start, restricted to only the <code>~/claude_workspace</code> directory. | Claude Code will start, restricted to only the <code>~/claude_workspace</code> directory. | ||
== True Filesystem Isolation == | |||
The standard Distrobox setup above has two surfaces that reach the host filesystem even inside the container: | |||
# '''Shared home directory''' — Distrobox mounts your real <code>~</code> inside the container. Anything written to <code>~/.config</code>, <code>~/.local</code>, <code>~/.bashrc</code>, etc. affects the host immediately. | |||
# '''<code>/run/host</code> mounted read-write''' — Distrobox mounts the entire host root filesystem at <code>/run/host</code> with write access, meaning code inside the container can modify host files outside the home directory. | |||
Firejail (Step 6) protects against this within a session, but for a fully isolated container that protects the host at the OS level, create the container with a '''separate home directory''' and <code>/run/host</code> mounted read-only: | |||
<pre> | |||
# Create a dedicated sandbox home directory on the host | |||
mkdir -p ~/sandbox-homes/claude-isolated | |||
# Create the isolated container | |||
distrobox create \ | |||
--name claude-isolated \ | |||
--image ubuntu:24.04 \ | |||
--home ~/sandbox-homes/claude-isolated \ | |||
--additional-flags "--mount type=bind,source=/,target=/run/host,ro" | |||
</pre> | |||
Enter it the same way: | |||
distrobox enter claude-isolated | |||
With this setup: | |||
* Claude Code can only write to <code>~/sandbox-homes/claude-isolated/</code> — your real home directory is untouched | |||
* <code>/run/host</code> is read-only — host filesystem cannot be modified from inside the container | |||
* System package installs (<code>apt</code>, <code>pip</code>) remain container-only as before | |||
* If you delete <code>~/sandbox-homes/claude-isolated/</code> after a session, no trace remains on the host | |||
=== What remains shared even with isolation === | |||
{| class="wikitable" | |||
|- | |||
! Surface !! Isolated? !! Notes | |||
|- | |||
| Host home directory || ✅ Yes || Separate sandbox home used instead | |||
|- | |||
| Host filesystem via <code>/run/host</code> || ✅ Yes || Mounted read-only | |||
|- | |||
| System packages || ✅ Yes || Container overlay layer | |||
|- | |||
| Network || ❌ No || Container shares host network namespace; add <code>--network=slirp4netns</code> to <code>--additional-flags</code> to isolate | |||
|- | |||
| Linux kernel || ❌ No || Rootless container shares the host kernel (acceptable for most threat models) | |||
|- | |||
| X11/Wayland display || ❌ No || GUI apps render on host desktop | |||
|} | |||
== What Each Layer Protects == | == What Each Layer Protects == | ||
| Line 179: | Line 222: | ||
* Claude Code needs network access to reach the Anthropic API, so network is not blocked by default. Add <code>--net=none</code> to <code>run_claude.sh</code> to fully disable networking. | * Claude Code needs network access to reach the Anthropic API, so network is not blocked by default. Add <code>--net=none</code> to <code>run_claude.sh</code> to fully disable networking. | ||
* If <code>~/.claude</code> is read-only, Claude Code cannot write session data (login tokens). Remove the <code>--read-only</code> line from the script if you wish to persist logins between sessions, though this slightly lowers security. | * If <code>~/.claude</code> is read-only, Claude Code cannot write session data (login tokens). Remove the <code>--read-only</code> line from the script if you wish to persist logins between sessions, though this slightly lowers security. | ||
* Distrobox shares the home directory with the host | * By default, Distrobox shares the home directory with the host. Use the isolated container setup in the '''True Filesystem Isolation''' section above to prevent this. | ||
== Why the Guide Uses Distrobox (The "Burner" Concept) == | == Why the Guide Uses Distrobox (The "Burner" Concept) == | ||
| Line 199: | Line 242: | ||
* [https://github.com/89luca89/distrobox Distrobox] | * [https://github.com/89luca89/distrobox Distrobox] | ||
* [https://firejail.wordpress.com/ Firejail] | * [https://firejail.wordpress.com/ Firejail] | ||
* [https://github.com/netblue30/firejail Firejail GitHub] | * [https://github.com/netblue30/firejail Firejail GitHub] | ||
Revision as of 13:25, 20 February 2026
Sandboxing Claude Code with Distrobox and Firejail
Overview
This guide documents how to run Claude Code in an isolated environment using two layers of sandboxing:
- Distrobox — runs Claude Code inside a Linux container, isolating it from the host system.
- Firejail — runs inside the container and further restricts Claude Code to a single project directory.
This protects against malicious prompt injection by limiting what Claude Code can access, even if it is tricked into running harmful commands.
Prerequisites
- A Linux host (Fedora, Ubuntu, Arch, etc.)
- Distrobox installed on the host
- A Claude Code account and API access
Step 1: Install Distrobox on the Host
Install distrobox on your host system:
sudo apt install distrobox # Debian/Ubuntu sudo dnf install distrobox # Fedora yay -S distrobox # Arch (AUR)
Step 2: Create a Distrobox Container
Create a new container (Ubuntu-based in this example):
distrobox create --name claude-container --image ubuntu:24.04
Enter the container:
distrobox enter claude-container
Step 3: Install Claude Code Inside the Container
Inside the distrobox container, install Node.js (if not already present) and Claude Code:
npm install -g @anthropic-ai/claude-code
Log in and verify it works:
claude
Step 4: Create a Dedicated Project Directory
Inside the container, create the directory where all Claude Code work will happen:
mkdir -p ~/claude_workspace cd ~/claude_workspace
This is the only directory Claude Code will be able to access when sandboxed.
Step 5: Install Firejail Inside the Container
Inside the distrobox container:
sudo apt install firejail
Verify the installation:
firejail --version
Step 6: Create the Launcher Script
Inside the project directory (~/claude_workspace), create the launcher script run_claude.sh:
nano ~/claude_workspace/run_claude.sh
With the following contents:
#!/bin/bash
# Launch Claude Code sandboxed to this directory using firejail
# Usage: ./csb.sh [claude args...]
WORK_DIR="$(cd "$(dirname "$0")" && pwd)"
CLAUDE_DIR="$HOME/.claude"
# Define NVM_DIR at the top so it's ready when needed
NVM_DIR="$HOME/.nvm"
# Check firejail is installed
if ! command -v firejail &>/dev/null; then
echo "Error: firejail is not installed. Install with: sudo apt install firejail"
exit 1
fi
# Check claude is installed
if ! command -v claude &>/dev/null; then
echo "Error: claude is not installed or not in PATH"
exit 1
fi
CLAUDE_BIN="$(which claude)"
echo "Starting Claude Code in sandbox..."
echo " Allowed directory: $WORK_DIR"
echo " Config directory: $CLAUDE_DIR (read-write)"
echo " NVM directory: $NVM_DIR"
echo ""
exec firejail --noprofile \
--whitelist="$WORK_DIR" \
--whitelist="$CLAUDE_DIR" \
--whitelist="$NVM_DIR" \
--noroot \
--caps.drop=all \
"$CLAUDE_BIN" "$@"
Make it executable:
chmod +x ~/claude_workspace/run_claude.sh
Step 7: Launch Claude Code in the Sandbox
Every time you want to use Claude Code, follow these steps:
1. Enter your distrobox container:
distrobox enter claude-container
2. Navigate to the project directory:
cd ~/claude_workspace
3. Run the launcher script:
./run_claude.sh
Claude Code will start, restricted to only the ~/claude_workspace directory.
True Filesystem Isolation
The standard Distrobox setup above has two surfaces that reach the host filesystem even inside the container:
- Shared home directory — Distrobox mounts your real
~inside the container. Anything written to~/.config,~/.local,~/.bashrc, etc. affects the host immediately. /run/hostmounted read-write — Distrobox mounts the entire host root filesystem at/run/hostwith write access, meaning code inside the container can modify host files outside the home directory.
Firejail (Step 6) protects against this within a session, but for a fully isolated container that protects the host at the OS level, create the container with a separate home directory and /run/host mounted read-only:
# Create a dedicated sandbox home directory on the host mkdir -p ~/sandbox-homes/claude-isolated # Create the isolated container distrobox create \ --name claude-isolated \ --image ubuntu:24.04 \ --home ~/sandbox-homes/claude-isolated \ --additional-flags "--mount type=bind,source=/,target=/run/host,ro"
Enter it the same way:
distrobox enter claude-isolated
With this setup:
- Claude Code can only write to
~/sandbox-homes/claude-isolated/— your real home directory is untouched /run/hostis read-only — host filesystem cannot be modified from inside the container- System package installs (
apt,pip) remain container-only as before - If you delete
~/sandbox-homes/claude-isolated/after a session, no trace remains on the host
What remains shared even with isolation
| Surface | Isolated? | Notes |
|---|---|---|
| Host home directory | ✅ Yes | Separate sandbox home used instead |
Host filesystem via /run/host |
✅ Yes | Mounted read-only |
| System packages | ✅ Yes | Container overlay layer |
| Network | ❌ No | Container shares host network namespace; add --network=slirp4netns to --additional-flags to isolate
|
| Linux kernel | ❌ No | Rootless container shares the host kernel (acceptable for most threat models) |
| X11/Wayland display | ❌ No | GUI apps render on host desktop |
What Each Layer Protects
| Layer | What it does | What it blocks |
|---|---|---|
| Distrobox | Runs everything in a container | Protects host system files, host packages, and host configuration from changes |
| Firejail | Restricts filesystem access within the container | Blocks access to everything outside ~/claude_workspace, prevents privilege escalation, drops Linux capabilities
|
| run_claude.sh | Automates launching with the correct flags | Ensures you never accidentally run Claude Code without the sandbox |
Verifying the Sandbox Works
Once Claude Code is running inside the sandbox, test it by asking Claude to:
- Read a file outside the project directory — should fail
- Run
ls ~— should only show whitelisted directories - Run
sudo anything— should be blocked - Read
~/.ssh/id_rsa— should be inaccessible
Summary of Commands
# On the host — enter the container distrobox enter claude-container # Inside the container — go to the project directory cd ~/claude_workspace # Launch Claude Code in the sandbox ./run_claude.sh
Limitations
- Firejail is Linux-only; this will not work on macOS or Windows.
- Claude Code needs network access to reach the Anthropic API, so network is not blocked by default. Add
--net=nonetorun_claude.shto fully disable networking. - If
~/.claudeis read-only, Claude Code cannot write session data (login tokens). Remove the--read-onlyline from the script if you wish to persist logins between sessions, though this slightly lowers security. - By default, Distrobox shares the home directory with the host. Use the isolated container setup in the True Filesystem Isolation section above to prevent this.
Why the Guide Uses Distrobox (The "Burner" Concept)
The "Burner Workflow" is designed to give the AI agent extensive permissions (e.g., auto-allow mode, running system commands, installing packages) without risking your actual computer. Distrobox is used to create a disposable container that feels like your native terminal but is actually isolated.
- Safety with High Permissions: If you let Claude Code run
rm -rfor install 50 different Node.js packages in a Distrobox, your main system remains untouched. If you do this on your host machine, you risk breaking your OS. - Dependency Hygiene: Claude Code agents often need to install tools (compilers, Python libraries, etc.) to complete tasks. Distrobox keeps this "junk" inside the box. When you are done, you can simply delete the box.
- Better Integration than Docker: Unlike a raw Docker container, Distrobox allows the AI to easily access your home directory files (if mapped) and use your host's terminal tools, making the workflow smoother while still keeping the execution environment separate.
2. Can You Skip It?
- Yes, if: You are just testing Claude Code, only plan to edit specific files, and will manually approve every command it tries to run (the default "safe" mode). Anthropic provides built-in sandboxing that is sufficient for basic use.
- No, if: You want to follow the "Burner" methodology—meaning you want to set the agent to autonomous mode (skipping permission prompts) or let it freely install tools. In this case, skipping the Distrobox layer is dangerous and defeats the purpose of the guide.
Summary
If you are following that specific wiki guide to build an autonomous or self-healing dev environment, do not skip the Distrobox step. It is the safety net that allows you to run the "burner" logic without nuking your daily driver.