README.md: - Add skip parameters example (-SkipVNC, -SkipOllama) - Document VNC password prompt and minimum length - Update requirements to show ISO creation fallbacks CLAUDE.md: - Add Windows script editing section - Add Windows security patterns section - Add Windows testing instructions - Update VNC password minimum from 6 to 8 chars - Document checksum verification for Windows Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
8.2 KiB
8.2 KiB
CLAUDE.md
Project Memory
This project uses three documentation files as persistent memory. You must keep these files up to date when making changes:
| File | Purpose | Update When |
|---|---|---|
CLAUDE.md |
Technical context for Claude Code sessions | Adding new patterns, conventions, or implementation details |
CHANGELOG.md |
Version history following Keep a Changelog format | Every commit (add entry, bump version) |
README.md |
User-facing documentation | Changing user-visible behavior, adding features, or modifying usage |
Versioning Rules
- Use semantic versioning (MAJOR.MINOR.PATCH)
- Increment PATCH for bug fixes and minor updates
- Increment MINOR for new features and enhancements
- Increment MAJOR for breaking changes
- Tag every commit with its version:
git tag -a vX.Y.Z -m "Description"
Project Overview
This repository provides scripts for creating isolated development sandboxes for Claude Code on macOS (OrbStack) and Windows (Hyper-V). Both platforms offer full VM isolation for safely running AI coding assistants with elevated permissions.
Supported platforms:
- macOS: OrbStack VMs (ARM64 Apple Silicon)
- Windows: Hyper-V VMs (maximum security, stronger than WSL2)
Repository Structure
setup_env.sh - macOS script (OrbStack host mode + Linux VM provisioning)
setup_env_windows.ps1 - Windows script (Hyper-V with cloud-init)
WINDOWS_PLAN.md - Windows implementation plan and security rationale
config.env.example - Example credentials file
config.env - User credentials (gitignored, created on first run)
.gitignore - Ignores config.env
README.md - User-facing documentation
CHANGELOG.md - Version history (Keep a Changelog format)
CLAUDE.md - This file (context for Claude Code sessions)
How the Script Works
The script has two modes, detected via uname -s:
- Darwin (macOS): Orchestrator mode. Checks for OrbStack, reads/creates
config.env, creates a VM, copies itself in, runs itself inside the VM with--non-interactive. - Linux (VM): Provisioning mode. Installs all tools, configures PostgreSQL, sets up VNC, installs Claude Code plugins.
This means ./setup_env.sh my-vm on macOS does everything end-to-end.
Key Technical Details
- Target environment: OrbStack Ubuntu VM on macOS Apple Silicon (ARM64)
- Version manager: mise (manages Node.js, Erlang, Elixir)
- Versions: All tools use latest by default. Erlang/Elixir versions can be configured at the top of
setup_env.sh(ERLANG_VERSION,ELIXIR_VERSION) - set to "latest" or pin to specific versions - PostgreSQL auth: Peer for local socket, scram-sha-256 for all TCP connections (localhost and network)
- Browser: Chromium (no Chrome ARM64 Linux builds exist), symlinked to
google-chrome - VNC: TigerVNC + XFCE on display :1 (port 5901), controlled via
vnc-start/vnc-stophelpers in~/bin - Shared credentials:
config.envstores git name/email only; VNC password is prompted each time (never stored)
Working on This Project
Editing setup_env.sh
- The macOS host-mode block is at the top (inside the
if [[ "$(uname -s)" == "Darwin" ]]block) - The Linux VM-mode block is everything after that conditional
- Version numbers are defined as variables at the top (
ERLANG_VERSION,ELIXIR_VERSION) - All installation steps must be idempotent (safe to run multiple times)
- Use
log_info,log_warn,log_errorhelpers for output - New apt packages go in the base dependencies section
- New Claude plugins go in the appropriate array (
ANTHROPIC_PLUGINSorSUPERPOWERS_PLUGINS) - Redirect verbose output to
$LOG_FILE, show only meaningful progress to the user - The
LOG_FILEvariable is only set in VM mode (not available in macOS host mode) - Each optional component is wrapped in
prompt_install "Name" "Description"— this handles both interactive prompts and--yes/--non-interactiveauto-accept - Track dependency flags (
INSTALLED_NODE,INSTALLED_CHROMIUM) to skip dependent components gracefully
Script Conventions
set -euo pipefailis enforced - handle potential failures with|| trueor explicit checks- Use
command_existsto check for already-installed tools - Use
apt-get(notapt) for scripting reliability - Quote all variable expansions
- Use
findfor PostgreSQL config paths (version-agnostic) - The
--non-interactiveflag is for VM mode (implies--yes); macOS mode always uses config.env --yes/-yaccepts all components without prompting but still allows interactive credential entryMISE_GLOBAL_CONFIG_FILEandMISE_CONFIG_DIRare set to prevent OrbStack host-mount config pollution
Security Patterns (macOS/Linux)
- Input validation: Use
validate_vm_name(),validate_vnc_password(),validate_safe_input()for all user inputs - Safe config loading: Use
load_config_safely()which parses key=value pairs without shell execution (neversource) - Credential passing: Base64-encode values before passing to VM via
orb runto prevent shell injection - Download helper: Use
download_verified_binary()for binary downloads (supports optional checksum verification) - Temp files: Always use
mktempwith restrictive permissions (chmod 600/700) - Symlinks: Check with
[ ! -e path ](not[ ! -L path ]) to avoid overwriting existing files - Architecture detection: Use
detect_architecture()for portable binary downloads
Editing setup_env_windows.ps1
- PowerShell script for Windows Hyper-V VM creation
- Uses Ubuntu cloud images with cloud-init for automated provisioning
- Supports ARM64 architecture detection for Windows on ARM
- Skip parameters:
-SkipVNC,-SkipPostgreSQL,-SkipOllama,-SkipPlaywright - ISO creation fallback chain: oscdimg → WSL genisoimage → IMAPI2 COM
- Log file created at
$env:TEMP\setup_env_windows_<timestamp>.log
Security Patterns (Windows)
- Input validation: Use
Test-GitName,Test-GitEmail,Test-VMPassword,Test-VNCPasswordfor all user inputs - Config file security: ACL set to owner-only before writing content (no race condition)
- Config validation: Loaded config.env values are re-validated to detect tampering
- Checksum verification: Ubuntu image verified against SHA256 checksums from Canonical
- Cleanup on failure:
Invoke-Cleanupremoves partial VM, disk, and ISO on errors - Hosts file backup: Created before modification, removed on success, kept on failure
- Cloud-init ISO: Contains passwords in plaintext; user reminded to remove after first boot
Testing
There are no automated tests. To test changes:
macOS:
- Remove an existing test VM:
orb delete test-sandbox - Run:
./setup_env.sh test-sandbox - Verify provisioning completes
- Run again to verify idempotency:
ssh test-sandbox@orb -- bash /tmp/setup_env.sh --non-interactive(will need env vars) - Test VNC:
ssh test-sandbox@orb -- vnc-start, thenopen vnc://test-sandbox.orb.local:5901 - Clean up:
orb delete test-sandbox
Windows:
- Remove existing test VM:
Stop-VM -Name test-sandbox -Force; Remove-VM -Name test-sandbox -Force - Run:
.\setup_env_windows.ps1 -VMName test-sandbox - Verify provisioning completes (check
/var/log/provision.login VM) - Test SSH:
ssh -i $env:USERPROFILE\.ssh\id_ed25519_test-sandbox dev@test-sandbox.local - Clean up:
Stop-VM -Name test-sandbox -Force; Remove-VM -Name test-sandbox -Force
Security Considerations
config.envis chmod 600 / owner-only ACL and gitignored (stores git name/email only, never passwords)- PostgreSQL uses scram-sha-256 for all TCP connections (peer auth for local socket)
- The script refuses to run as root inside the VM
- VNC password is required (min 8 chars), validated to block shell metacharacters, never stored
- VNC binds to all interfaces (
-localhost no) to allow connections from the host — this is intentional and documented - All user inputs are validated before use to prevent command injection
- External scripts (mise, ollama) are downloaded to temp files and validated before execution
- Host filesystem access is disabled inside the VM for isolation
- Windows: Ubuntu image downloads are verified against SHA256 checksums