Integrates Python as a selectable component alongside existing Node.js and Erlang options Updates component descriptions to reflect mise's expanded language support Includes pip upgrade during Python installation for package management Fixes Tidewave CLI download URL and architecture detection for improved reliability |
||
|---|---|---|
| .gitignore | ||
| CHANGELOG.md | ||
| CLAUDE.md | ||
| config.env.example | ||
| README.md | ||
| setup_env.sh | ||
| setup_env_windows.ps1 | ||
Secure AI Coding Sandboxes
Disposable, isolated Linux VMs for running Claude Code with --dangerously-skip-permissions. One command creates a fully provisioned environment. Blow it away and recreate it in minutes.
The VM is a real Linux machine with its own filesystem, network, and process space — complete isolation from your host with easy access for development.
| Platform | Script | Isolation Level |
|---|---|---|
| macOS | setup_env.sh (OrbStack) |
Full VM isolation |
| Windows | setup_env_windows.ps1 (Hyper-V) |
Full VM isolation |
Why This Exists
Running claude --dangerously-skip-permissions on your host machine means Claude can execute arbitrary commands, install packages, modify system files, and access everything on your disk. That's powerful for autonomous coding but risky on a machine with your SSH keys, credentials, and personal files.
These scripts create throwaway VMs where Claude can run unrestricted:
- Isolated filesystem — Claude can't touch your host files, keys, or configs
- Isolated network — services run on their own IP, no port conflicts with your host
- Disposable — delete and recreate in one command
- Multiple VMs — run separate sandboxes per project with shared git credentials
- Full access from host — edit files in your editor, browse databases, view running apps
Quick Start (macOS)
# Create a sandbox, SSH in, run Claude unrestricted
./setup_env.sh my-project
ssh my-project@orb
claude --dangerously-skip-permissions
If anything goes wrong: orb delete my-project && ./setup_env.sh my-project
macOS Setup
# Create and provision a VM (one command from macOS)
./setup_env.sh my-sandbox
On first run, you'll be prompted for git commit author name and email. These are saved to config.env and reused for all future VMs. You'll also get an interactive checklist to select which components to install. If you select VNC, you'll be prompted for a VNC password (this is never stored and must be entered each time).
# Create additional VMs — reuses config.env, shows component picker
./setup_env.sh my-other-project
./setup_env.sh elixir-playground
When run manually inside a VM, you're prompted for each component individually:
# Inside a VM — interactive, prompts per component
./setup_env.sh
# Inside a VM — accept all without prompting
./setup_env.sh -y
./setup_env.sh --yes
macOS Requirements
- macOS with Apple Silicon (ARM64)
- OrbStack installed (
brew install orbstack)
Quick Start (Windows)
# Run as Administrator
.\setup_env_windows.ps1 -VMName my-project
# Connect via SSH (after provisioning)
ssh -i $env:USERPROFILE\.ssh\id_ed25519_my-project dev@my-project.local
# Run Claude unrestricted
claude --dangerously-skip-permissions
If anything goes wrong: Remove-VM -Name my-project -Force then run the script again.
Windows Setup
# Create and provision a VM (run as Administrator)
.\setup_env_windows.ps1 -VMName my-sandbox
# Customize resources
.\setup_env_windows.ps1 -VMName my-sandbox -MemoryGB 16 -DiskGB 100 -CPUs 8
On first run, you'll be prompted for:
- Git commit author name and email (saved to
config.env) - VM user password (not stored, used for initial setup)
Windows Requirements
- Windows 10/11 Pro, Enterprise, or Education (Hyper-V not available on Home)
- Hyper-V enabled:
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All - Windows ADK (for cloud-init ISO creation): Download
- Administrator privileges
Why Hyper-V (not WSL2)?
WSL2 is convenient but provides weaker isolation:
- Shares kernel with all WSL2 instances
- Host filesystem mounted by default
- Can launch Windows executables from Linux
- Network traffic bypasses Windows firewall
Hyper-V provides maximum security:
- Separate kernel per VM
- Complete filesystem isolation
- Own network stack
- No Windows integration by default
What Gets Installed
All components are optional — deselect what you don't need in the interactive picker.
| Tool | Version | Purpose |
|---|---|---|
| mise | latest | Version manager for runtimes |
| Node.js | LTS | JavaScript runtime |
| Erlang | latest | BEAM VM |
| Elixir | latest | Elixir language |
| Chromium | system | Browser automation target |
| Playwright | latest | Browser testing framework |
| PostgreSQL | system default | Database |
| Ollama | latest | Local LLM inference |
| Claude Code | latest | AI coding assistant (Anthropic) |
| OpenCode | latest | Open-source AI coding assistant (multi-provider) |
| Tidewave | latest | Elixir/Phoenix MCP server for AI tools |
| yq | latest | YAML processor |
| watchexec | latest | File watcher (via cargo) |
| TigerVNC + XFCE | system | VNC access for browser login flows |
Connecting from macOS
SSH
# Shell into the VM (no key setup required)
ssh my-sandbox@orb
# Run a command directly
ssh my-sandbox@orb -- ls ~/projects
# Run Claude unrestricted
ssh my-sandbox@orb -- claude --dangerously-skip-permissions
OrbStack handles SSH key configuration automatically.
Editing Files
Your editor connects to the VM over SSH. You edit files as if they were local — full LSP support, syntax highlighting, file tree, integrated terminal.
Zed:
Cmd+Shift+P-> "Open Remote Folder"- Enter:
my-sandbox@orb:~/projects
VS Code / Cursor:
- Install the "Remote - SSH" extension
Cmd+Shift+P-> "Remote-SSH: Connect to Host"- Enter:
my-sandbox@orb - Open folder:
~/projects
Finder (direct filesystem access):
/Volumes/OrbStack/my-sandbox/home/<user>/
Viewing Running Apps
Services running in the VM are accessible from your Mac via <vm-name>.orb.local:
# Phoenix/Rails/Next.js dev server running on port 4000 inside the VM
open http://my-sandbox.orb.local:4000
# Or use port forwarding if the app only binds to localhost
ssh -L 4000:localhost:4000 my-sandbox@orb
PostgreSQL, Redis, or any service listening on the VM's interfaces is reachable at my-sandbox.orb.local:<port> from your Mac — no extra configuration.
VNC (Browser Access)
For tasks requiring a visible browser (e.g., Claude Code OAuth login):
# Start VNC server inside the VM
ssh my-sandbox@orb -- vnc-start
# Connect from macOS (opens Screen Sharing.app)
open vnc://my-sandbox.orb.local:5901
# Stop when done (saves resources)
ssh my-sandbox@orb -- vnc-stop
macOS Screen Sharing (built-in)
open vnc://my-sandbox.orb.local:5901
Enter your VNC password when prompted.
RealVNC Viewer
- Download from https://www.realvnc.com/en/connect/download/viewer/
- Enter address:
my-sandbox.orb.local:5901 - When prompted for credentials, enter your VNC password (username can be left blank)
TigerVNC Viewer
# Install via Homebrew
brew install tiger-vnc
# Connect
vncviewer my-sandbox.orb.local:5901
Enter your VNC password when prompted.
Connection details for any VNC client
- Host:
my-sandbox.orb.local - Port:
5901(display:1) - Password: the VNC password from
config.env - Resolution: 1280x800 (configurable in
~/bin/vnc-start)
PostgreSQL
A superuser matching your Linux username and a dev database are created automatically.
Auth model:
- Local socket (
psql dev): peer auth (OS username must match PG role) - Localhost TCP (127.0.0.1): scram-sha-256 (password required)
- Host network (192.168.0.0/16, i.e., from macOS): scram-sha-256
From inside the VM
psql dev # Connect to dev database
psql -l # List databases
createdb myapp_dev # Create a new database
From macOS
# Direct (requires: brew install libpq)
psql -h my-sandbox.orb.local -U <user> -d dev
Connection strings
# Elixir/Phoenix
postgres://<user>@my-sandbox.orb.local/myapp_dev
# Generic
host=my-sandbox.orb.local port=5432 dbname=dev user=<user>
DataGrip
- New Data Source -> PostgreSQL
- SSH/SSL tab: Check "Use SSH tunnel", Host:
my-sandbox@orb, Auth: Key pair - General tab: Host:
localhost, Port:5432, User: your VM username, Database:dev, No password - Test Connection -> Apply
DBeaver
- New Database Connection -> PostgreSQL
- SSH tab: Check "Use SSH Tunnel", Host:
my-sandbox.orb.local, Port:22, Auth: Public Key - Main tab: Host:
localhost, Port:5432, Database:dev, Username: your VM username, no password - Test Connection -> Finish
Creating additional databases
# From inside the VM
createdb myapp_dev
createdb myapp_test
# From macOS
ssh my-sandbox@orb -- createdb myapp_dev
Claude Code Plugins
The script installs these plugins at user scope:
Anthropic marketplace (anthropics/claude-code):
- code-review, code-simplifier, feature-dev, pr-review-toolkit, security-guidance, frontend-design
Superpowers marketplace (obra/superpowers):
- double-shot-latte, elements-of-style, superpowers, superpowers-chrome, superpowers-lab
MCP Servers:
playwright- Browser automation and screenshotssuperpowers-chrome- Direct Chrome/Chromium control (headless)
Configuration
All tools are configured to use the latest versions by default. Erlang and Elixir versions can be customized in setup_env.sh:
ERLANG_VERSION="latest" # or pin to specific version like "28.3.1"
ELIXIR_VERSION="latest" # or pin to specific version like "1.19.5-otp-28"
Shared credentials
Git credentials (name, email) are stored in config.env (gitignored). VNC passwords are never stored and must be entered each time you create a VM with VNC enabled.
To reset git credentials:
rm config.env
./setup_env.sh my-sandbox # will prompt again
Or copy the example and edit:
cp config.env.example config.env
# Edit config.env with your values
Managing VMs
# List all VMs
orb list
# Delete a VM (instant cleanup)
orb delete my-sandbox
# Stop a VM (preserves state, frees resources)
orb stop my-sandbox
# Start a stopped VM
orb start my-sandbox
# Nuclear option — delete and recreate
orb delete my-sandbox && ./setup_env.sh my-sandbox
Idempotency
The VM provisioning script is safe to run multiple times. It checks for existing installations before re-installing and avoids appending duplicate configuration lines.
Logs
Each provisioning run creates a log file at /tmp/setup_env_<timestamp>.log inside the VM with detailed output from package installations and any errors. Log files are created with mode 600 (owner-only access).
Security
The script includes several security hardening measures:
- Input validation: VM names, VNC passwords, and git credentials are validated against strict patterns
- No credential storage: VNC passwords are prompted each time and never written to disk
- Safe credential passing: Values are base64-encoded when passed to the VM to prevent shell injection
- Config file security:
config.envis created with mode 600 and parsed safely (not sourced) - Secure temp files: Uses
mktempwith restrictive permissions for all temporary files - Host filesystem isolation: macOS home directory access is disabled inside the VM
- PostgreSQL hardening: Uses peer auth for local sockets, scram-sha-256 for network connections