Compare commits

...

15 commits
v0.2.0 ... main

Author SHA1 Message Date
guessthepw
2fb83ada34 Updates documentation for Windows security features
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>
2026-01-25 13:36:00 -05:00
guessthepw
ca12925111 Adds security hardening to Windows Hyper-V script
Security improvements:
- SHA256 checksum verification for Ubuntu image downloads
- Strict input validation for all user inputs (git name/email, passwords)
- Blocks shell metacharacters to prevent injection attacks
- Config file created with restricted ACL from the start
- VNC password minimum increased to 8 characters
- Security reminder to remove cloud-init ISO after first boot

Reliability improvements:
- ARM64 architecture detection for Windows on ARM
- Log file creation for troubleshooting
- Automatic cleanup on failure (VM, disk, ISO)
- Hosts file backup before modification

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 13:23:08 -05:00
guessthepw
65790ee3e2 Implements full Windows Hyper-V provisioning
Rewrites setup_env_windows.ps1 to fully implement WINDOWS_PLAN.md with:
- Fixed cloud-init password handling using chpasswd
- Multiple ISO creation fallbacks (oscdimg/WSL/IMAPI2)
- Component skip parameters for VNC, PostgreSQL, Ollama, Playwright
- VNC password support via base64 encoding
- BITS transfer for reliable downloads
- SSH readiness checking before showing connection info

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 12:52:58 -05:00
guessthepw
cc1277cd98 Fix Tidewave install, add Python to mise, document Windows plan
Fixes:
- Tidewave CLI now downloads from correct repo (tidewave_app)
  with proper musl binary naming convention

Features:
- Python runtime managed by mise instead of system apt
- Python added as selectable component in interactive menu

Documentation:
- WINDOWS_PLAN.md explains Hyper-V vs WSL2 security tradeoffs
- Documents CVEs affecting WSL2 (2024-20681, 2025-9074, 2025-53788)
- Describes full implementation architecture and workflow

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 12:48:35 -05:00
guessthepw
77093a0ce6 Adds Python support via mise version manager
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
2026-01-25 12:47:45 -05:00
guessthepw
70c2559d40 Add Windows Hyper-V support for maximum security isolation
Creates setup_env_windows.ps1 PowerShell script that:
- Provisions full Hyper-V VMs (not WSL2) for complete isolation
- Uses Ubuntu cloud images with cloud-init for automated setup
- Generates SSH keys for passwordless access
- Adds VMs to hosts file for easy <name>.local access
- Disables integration services by default for security

Hyper-V provides stronger isolation than WSL2:
- Separate kernel per VM
- Complete filesystem isolation (no /mnt/c mount)
- Own network stack (no firewall bypass)
- No ability to launch Windows programs from Linux

Also updates README with cross-platform quick start guides
and security comparison between WSL2 and Hyper-V.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 12:18:25 -05:00
guessthepw
2861664a03 Add OpenCode and Tidewave CLI support
- OpenCode: Open-source AI coding assistant (npm install -g opencode-ai)
  Supports multiple LLM providers including OpenAI, Anthropic, Gemini

- Tidewave: Elixir/Phoenix MCP server for AI-powered development
  Downloads binary from GitHub releases with ELF validation
  Enables runtime introspection, SQL queries, and code evaluation

Both tools are optional components in the interactive installer.
Tidewave is automatically skipped if Erlang is not selected.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 12:16:06 -05:00
guessthepw
63bcc0aea3 Add error checking for base64 decode in VM bootstrap
Ensures early failure with clear error messages if credential
decoding fails during VM provisioning.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 09:36:02 -05:00
guessthepw
26501daa4e Fix critical security vulnerabilities from audit
- Rustup: Download script to temp file with shebang/size validation
  before execution, matching mise/ollama pattern (line 1119)

- SKIP_EXPORTS: Refactor from embedded shell commands to base64-encoded
  list decoded safely in VM, eliminating injection risk (line 478)

- Playwright symlink: Validate path is executable and within expected
  cache directory before creating system symlinks (line 1053)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 09:34:24 -05:00
guessthepw
cbc379c0cc Add project memory system with versioning guidelines
Establishes CLAUDE.md, CHANGELOG.md, and README.md as persistent
project memory. Adds documentation update triggers and semantic
versioning rules to ensure context is maintained across sessions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 09:29:37 -05:00
guessthepw
b3ed5e66a5 Add CHANGELOG.md with version history
Documents all releases from v0.1.0 through v0.6.0 following
Keep a Changelog format with semantic versioning.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 09:28:50 -05:00
guessthepw
9ee89df424 Improves security and simplifies version management
Switches all tools to use latest versions by default instead of pinning specific versions, reducing maintenance overhead while still allowing customization for Erlang and Elixir.

Enhances security measures by documenting input validation patterns, safe config loading practices, and credential handling procedures. Updates PostgreSQL authentication to use scram-sha-256 for all TCP connections.

Clarifies that VNC passwords are never stored and must be entered each time, improving the security posture of credential management.

Simplifies tool installation by removing version pinning constraints and using native package managers where appropriate.
2026-01-25 09:25:57 -05:00
guessthepw
20fa7fa3c5 Hardens security against injection attacks
Prevents shell injection through input validation and safe parameter passing
Replaces direct sourcing with manual config parsing to avoid code execution
Downloads and validates install scripts before execution instead of piping
Uses base64 encoding for secure VM parameter transmission
Adds checksum verification for binary downloads
Creates secure temporary directories and files with proper permissions

Addresses multiple security vulnerabilities in environment setup process
2026-01-25 09:25:57 -05:00
guessthepw
8c6fb6c3bc Adds parallel execution and dashboard to setup script
Replaces sequential installation with parallel step execution
Introduces real-time progress dashboard with spinner and status
Removes color variables to improve terminal compatibility
Restructures logging with per-step files for better debugging

Significantly reduces total setup time by running independent steps concurrently
2026-01-25 09:25:57 -05:00
guessthepw
d7788a5212 Creates dual-mode development sandbox setup
Implements orchestration on macOS and provisioning on Linux for isolated Claude Code environments

Adds interactive component selection with visual menu interface
Enables secure VM creation with disabled host filesystem access
Provides comprehensive toolchain including PostgreSQL, Erlang/Elixir, and browser automation
Configures VNC desktop access for OAuth workflows and browser-based tasks
2026-01-25 09:25:57 -05:00
8 changed files with 3479 additions and 230 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
config.env

169
CHANGELOG.md Normal file
View file

@ -0,0 +1,169 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.14.1] - 2025-01-25
### Changed
- Updated README.md with Windows skip parameters and VNC password info
- Updated CLAUDE.md with Windows script documentation and security patterns
- Fixed VNC password minimum documentation (6 → 8 chars)
## [0.14.0] - 2025-01-25
### Security
- Add SHA256 checksum verification for Ubuntu cloud image downloads (prevents MITM attacks)
- Add strict input validation for git name, email, VM password, and VNC password
- Validate loaded config.env values to detect tampering
- VNC password minimum increased from 6 to 8 characters
- Block shell metacharacters in all user inputs to prevent injection
- Config file created with restricted ACL from the start (no race condition window)
- Add security reminder to remove cloud-init ISO after first boot (contains passwords)
### Added
- ARM64 architecture detection for Windows on ARM devices
- Log file creation at `$env:TEMP\setup_env_windows_<timestamp>.log`
- Cleanup on failure: automatically removes partial VM, disk, and ISO on error
- Hosts file backup before modification (removed on success, kept on failure)
- Input validation functions: `Test-GitName`, `Test-GitEmail`, `Test-VMPassword`, `Test-VNCPassword`
- Checksum caching to avoid re-downloading verification data
### Changed
- Ubuntu image URL now uses detected architecture instead of hardcoded amd64
- All major operations now log to file for troubleshooting
- VM creation wrapped in try/catch with automatic cleanup on failure
## [0.13.0] - 2025-01-25
### Changed
- Rewrote `setup_env_windows.ps1` to fully implement WINDOWS_PLAN.md
- Password handling uses cloud-init `chpasswd` with plaintext (type: text) instead of broken hash generation
- Multiple ISO creation methods with fallback chain: oscdimg → WSL genisoimage → IMAPI2 COM
- Downloads use BITS transfer for reliability with progress reporting
- SSH readiness checking with timeout before displaying connection info
### Added
- Component skip parameters: `-SkipVNC`, `-SkipPostgreSQL`, `-SkipOllama`, `-SkipPlaywright`
- VNC password support via base64 encoding in cloud-init
- Automatic hosts file cleanup when VM is deleted with `-Force`
- Proper prerequisite checking for Hyper-V, Windows edition, and admin privileges
### Fixed
- Cloud-init password configuration (was using bash syntax in PowerShell)
- ISO creation now works without Windows ADK by using WSL or IMAPI2 fallbacks
- Hosts file handling with proper admin privilege elevation
## [0.12.0] - 2025-01-25
### Added
- Python runtime management via mise (alongside Node.js, Erlang, Elixir)
- `WINDOWS_PLAN.md` documenting Hyper-V implementation strategy and security rationale
### Fixed
- Tidewave CLI download URL (now uses correct `tidewave_app` repo with musl binaries)
### Changed
- Python is now a selectable component managed by mise instead of system apt
## [0.11.0] - 2025-01-25
### Added
- Windows support via Hyper-V for maximum security isolation
- `setup_env_windows.ps1` PowerShell script with full VM provisioning
- Ubuntu cloud image support with cloud-init automation
- SSH key generation for passwordless VM access on Windows
- Hosts file integration for easy `<vmname>.local` access
### Security
- Hyper-V provides stronger isolation than WSL2 (separate kernel, network, filesystem)
- No host integration services enabled by default
## [0.10.0] - 2025-01-25
### Added
- OpenCode: Open-source AI coding assistant with multi-provider support
- Tidewave CLI: Elixir/Phoenix MCP server for AI-powered development
- New component selection options for OpenCode and Tidewave
## [0.9.1] - 2025-01-25
### Fixed
- Add error checking for base64 decode operations in VM provisioning
- Add `set -e` to VM bootstrap script for early failure detection
## [0.9.0] - 2025-01-25
### Security
- Fix rustup pipe-to-shell vulnerability: now downloads to temp file with validation before execution
- Fix SKIP_EXPORTS command injection risk: refactored to use base64-encoded list instead of shell command string
- Fix Playwright symlink path validation: validates executable and path prefix before creating symlinks
## [0.8.0] - 2025-01-25
### Added
- Project memory system using CLAUDE.md, CHANGELOG.md, and README.md
- Versioning rules and documentation update guidelines in CLAUDE.md
## [0.7.0] - 2025-01-25
### Added
- CHANGELOG.md with version history following Keep a Changelog format
## [0.6.0] - 2025-01-25
### Changed
- All tools now use latest versions by default instead of pinning specific versions
- PostgreSQL authentication uses scram-sha-256 for all TCP connections
- Simplified tool installation by removing version pinning constraints
### Security
- VNC passwords are never stored and must be entered each time
- Added documentation for input validation patterns and safe config loading
## [0.5.0] - 2025-01-25
### Security
- Prevents shell injection through input validation and safe parameter passing
- Replaces direct sourcing with manual config parsing to avoid code execution
- Downloads and validates install scripts before execution instead of piping
- Uses base64 encoding for secure VM parameter transmission
- Adds checksum verification for binary downloads
- Creates secure temporary directories and files with proper permissions
## [0.4.0] - 2025-01-25
### Changed
- Replaces sequential installation with parallel step execution
- Introduces real-time progress dashboard with spinner and status
- Removes color variables to improve terminal compatibility
- Restructures logging with per-step files for better debugging
### Performance
- Significantly reduces total setup time by running independent steps concurrently
## [0.3.0] - 2025-01-25
### Added
- Dual-mode operation: orchestration on macOS, provisioning on Linux
- Interactive component selection with visual menu interface
- VNC desktop access for OAuth workflows and browser-based tasks
### Security
- Secure VM creation with disabled host filesystem access
## [0.2.0] - 2025-01-25
### Added
- OrbStack development sandbox setup script
- mise version manager with Node.js, Erlang, and Elixir support
- PostgreSQL 16 with remote access configuration
- Claude Code integration with multiple plugin marketplaces
- Chromium browser and Playwright for automation tasks
## [0.1.0] - 2025-01-25
### Added
- Initial project structure

147
CLAUDE.md Normal file
View file

@ -0,0 +1,147 @@
# 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-stop` helpers in `~/bin`
- **Shared credentials**: `config.env` stores 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_error` helpers for output
- New apt packages go in the base dependencies section
- New Claude plugins go in the appropriate array (`ANTHROPIC_PLUGINS` or `SUPERPOWERS_PLUGINS`)
- Redirect verbose output to `$LOG_FILE`, show only meaningful progress to the user
- The `LOG_FILE` variable 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-interactive` auto-accept
- Track dependency flags (`INSTALLED_NODE`, `INSTALLED_CHROMIUM`) to skip dependent components gracefully
### Script Conventions
- `set -euo pipefail` is enforced - handle potential failures with `|| true` or explicit checks
- Use `command_exists` to check for already-installed tools
- Use `apt-get` (not `apt`) for scripting reliability
- Quote all variable expansions
- Use `find` for PostgreSQL config paths (version-agnostic)
- The `--non-interactive` flag is for VM mode (implies `--yes`); macOS mode always uses config.env
- `--yes`/`-y` accepts all components without prompting but still allows interactive credential entry
- `MISE_GLOBAL_CONFIG_FILE` and `MISE_CONFIG_DIR` are 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 (never `source`)
- **Credential passing**: Base64-encode values before passing to VM via `orb run` to prevent shell injection
- **Download helper**: Use `download_verified_binary()` for binary downloads (supports optional checksum verification)
- **Temp files**: Always use `mktemp` with 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-VNCPassword` for 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-Cleanup` removes 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:**
1. Remove an existing test VM: `orb delete test-sandbox`
2. Run: `./setup_env.sh test-sandbox`
3. Verify provisioning completes
4. Run again to verify idempotency: `ssh test-sandbox@orb -- bash /tmp/setup_env.sh --non-interactive` (will need env vars)
5. Test VNC: `ssh test-sandbox@orb -- vnc-start`, then `open vnc://test-sandbox.orb.local:5901`
6. Clean up: `orb delete test-sandbox`
**Windows:**
1. Remove existing test VM: `Stop-VM -Name test-sandbox -Force; Remove-VM -Name test-sandbox -Force`
2. Run: `.\setup_env_windows.ps1 -VMName test-sandbox`
3. Verify provisioning completes (check `/var/log/provision.log` in VM)
4. Test SSH: `ssh -i $env:USERPROFILE\.ssh\id_ed25519_test-sandbox dev@test-sandbox.local`
5. Clean up: `Stop-VM -Name test-sandbox -Force; Remove-VM -Name test-sandbox -Force`
### Security Considerations
- `config.env` is 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

376
README.md
View file

@ -0,0 +1,376 @@
# 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)
```bash
# 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
```bash
# 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).
```bash
# 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:
```bash
# 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](https://orbstack.dev) installed (`brew install orbstack`)
## Quick Start (Windows)
```powershell
# 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
```powershell
# 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
# Skip optional components
.\setup_env_windows.ps1 -VMName my-sandbox -SkipVNC -SkipOllama
```
On first run, you'll be prompted for:
- Git commit author name and email (saved to `config.env`)
- VM user password (min 8 chars, not stored)
- VNC password if VNC is enabled (min 8 chars, not stored)
### 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`
- Administrator privileges
- One of: Windows ADK, WSL with genisoimage, or Windows 10+ (IMAPI2 fallback)
### 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
```bash
# 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:**
1. `Cmd+Shift+P` -> "Open Remote Folder"
2. Enter: `my-sandbox@orb:~/projects`
**VS Code / Cursor:**
1. Install the "Remote - SSH" extension
2. `Cmd+Shift+P` -> "Remote-SSH: Connect to Host"
3. Enter: `my-sandbox@orb`
4. 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`:
```bash
# 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):
```bash
# 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)
```bash
open vnc://my-sandbox.orb.local:5901
```
Enter your VNC password when prompted.
### RealVNC Viewer
1. Download from https://www.realvnc.com/en/connect/download/viewer/
2. Enter address: `my-sandbox.orb.local:5901`
3. When prompted for credentials, enter your VNC password (username can be left blank)
### TigerVNC Viewer
```bash
# 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
```bash
psql dev # Connect to dev database
psql -l # List databases
createdb myapp_dev # Create a new database
```
### From macOS
```bash
# 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
1. New Data Source -> PostgreSQL
2. **SSH/SSL** tab: Check "Use SSH tunnel", Host: `my-sandbox@orb`, Auth: Key pair
3. **General** tab: Host: `localhost`, Port: `5432`, User: your VM username, Database: `dev`, No password
4. Test Connection -> Apply
### DBeaver
1. New Database Connection -> PostgreSQL
2. **SSH** tab: Check "Use SSH Tunnel", Host: `my-sandbox.orb.local`, Port: `22`, Auth: Public Key
3. **Main** tab: Host: `localhost`, Port: `5432`, Database: `dev`, Username: your VM username, no password
4. Test Connection -> Finish
### Creating additional databases
```bash
# 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 screenshots
- `superpowers-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`:
```bash
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:
```bash
rm config.env
./setup_env.sh my-sandbox # will prompt again
```
Or copy the example and edit:
```bash
cp config.env.example config.env
# Edit config.env with your values
```
## Managing VMs
```bash
# 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.env` is created with mode 600 and parsed safely (not sourced)
- **Secure temp files**: Uses `mktemp` with 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

257
WINDOWS_PLAN.md Normal file
View file

@ -0,0 +1,257 @@
# Windows Hyper-V Implementation Plan
This document describes the plan for implementing secure, isolated development sandboxes on Windows using Hyper-V instead of WSL2.
## Why Hyper-V Over WSL2
### WSL2 Security Limitations
| Issue | Impact |
|-------|--------|
| **Shared kernel** | All WSL2 instances share Microsoft's Linux kernel |
| **Host filesystem access** | `/mnt/c` mounted by default, can access Windows files |
| **Bidirectional execution** | Linux can launch Windows executables |
| **Firewall bypass** | WSL2 outbound traffic bypasses Windows firewall rules |
| **Process visibility** | Windows has limited visibility into WSL2 processes |
| **Credential exposure** | Linux processes can potentially access Windows credentials |
### CVE History
- **CVE-2024-20681**: Local privilege escalation to SYSTEM via WSL
- **CVE-2025-9074**: Container escape via WSL2 filesystem sharing
- **CVE-2025-53788**: Undisclosed flaw in WSL/host communication
### Hyper-V Isolation Model
| Feature | Benefit |
|---------|---------|
| **Separate kernel** | Each VM runs its own Linux kernel |
| **Complete filesystem isolation** | No access to Windows files by default |
| **Own network stack** | Separate IP, no firewall bypass |
| **No Windows integration** | Cannot launch Windows programs |
| **Snapshot support** | Can checkpoint and restore VM state |
| **Hardware isolation** | Uses VT-x/AMD-V virtualization |
## Implementation Architecture
```
┌─────────────────────────────────────────────────────────────────┐
│ Windows Host │
│ │
│ ┌─────────────────────┐ ┌─────────────────────────────────┐ │
│ │ setup_env_windows.ps1│ │ Hyper-V Manager │ │
│ │ │ │ │ │
│ │ • Check prereqs │───▶│ ┌──────────────────────────┐ │ │
│ │ • Download image │ │ │ Ubuntu VM │ │ │
│ │ • Create cloud-init │ │ │ │ │ │
│ │ • Provision VM │ │ │ • Isolated filesystem │ │ │
│ │ • Configure network │ │ │ • Own network (NAT) │ │ │
│ └─────────────────────┘ │ │ • Claude Code + tools │ │ │
│ │ │ • No Windows access │ │ │
│ │ └──────────────────────────┘ │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
```
## Script Workflow
### Phase 1: Prerequisites Check
```powershell
# Verify environment
1. Check Administrator privileges
2. Check Windows edition (Pro/Enterprise/Education required)
3. Check Hyper-V enabled
4. Check for existing VM (handle -Force flag)
5. Find suitable network switch
```
### Phase 2: Configuration
```powershell
# Collect credentials
1. Load config.env if exists (git name/email)
2. Prompt for missing values
3. Prompt for VM password (not stored)
4. Generate SSH key pair for VM access
```
### Phase 3: Image Preparation
```powershell
# Prepare Ubuntu cloud image
1. Download Ubuntu cloud image (VHDX format)
2. Cache in $env:ProgramData\HyperV-DevSandbox\Images
3. Copy and resize for new VM
4. Generate cloud-init ISO with:
- User account configuration
- SSH key injection
- Package installation
- Setup script embedding
```
### Phase 4: VM Creation
```powershell
# Create Hyper-V VM
1. Create Generation 2 VM (UEFI)
2. Configure resources (CPU, RAM, disk)
3. Disable Secure Boot (for Ubuntu)
4. Attach cloud-init ISO
5. Disable integration services for isolation
6. Enable nested virtualization (for Docker)
```
### Phase 5: Provisioning
```powershell
# Start and provision
1. Start VM
2. Wait for IP assignment
3. Add to hosts file (<vmname>.local)
4. Cloud-init runs setup_env.sh internally
5. Display connection instructions
```
## Cloud-Init Configuration
```yaml
#cloud-config
hostname: <vmname>
users:
- name: dev
sudo: ALL=(ALL) NOPASSWD:ALL
ssh_authorized_keys:
- <generated-public-key>
packages:
- openssh-server
- curl
- git
write_files:
- path: /tmp/setup_env.sh
content: <base64-encoded-script>
runcmd:
- bash /tmp/setup_env.sh --non-interactive --yes
```
## Security Hardening
### VM Configuration
```powershell
# Disable integration services for maximum isolation
Disable-VMIntegrationService -Name "Guest Service Interface"
Disable-VMIntegrationService -Name "Heartbeat"
# Keep Time Synchronization and Shutdown for usability
```
### Network Isolation Options
1. **NAT (Default)**: VM can access internet, isolated from LAN
2. **Internal Only**: VM can only communicate with host
3. **Private**: Completely isolated network
### Firewall Rules (Optional)
```powershell
# Allow SSH access only
New-NetFirewallRule -Name "HyperV-SSH-$VMName" `
-Direction Inbound -LocalPort 22 -Protocol TCP `
-RemoteAddress <VM-IP> -Action Allow
```
## Requirements
### Windows Edition
- Windows 10/11 Pro
- Windows 10/11 Enterprise
- Windows 10/11 Education
- Windows Server 2016+
**Not supported**: Windows 10/11 Home (no Hyper-V)
### Hardware
- 64-bit processor with SLAT (Second Level Address Translation)
- VM Monitor Mode extensions (VT-x on Intel, AMD-V on AMD)
- Minimum 4 GB RAM (8+ GB recommended)
- BIOS/UEFI virtualization enabled
### Software
- Hyper-V enabled: `Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All`
- Windows ADK (for cloud-init ISO creation): [Download](https://docs.microsoft.com/en-us/windows-hardware/get-started/adk-install)
## Usage
### Create Sandbox
```powershell
# Basic usage (run as Administrator)
.\setup_env_windows.ps1 -VMName my-project
# With custom resources
.\setup_env_windows.ps1 -VMName my-project -MemoryGB 16 -DiskGB 100 -CPUs 8
# Replace existing VM
.\setup_env_windows.ps1 -VMName my-project -Force
```
### Connect to Sandbox
```powershell
# Via SSH (recommended)
ssh -i $env:USERPROFILE\.ssh\id_ed25519_<vmname> dev@<vmname>.local
# Via Hyper-V console
vmconnect localhost <vmname>
```
### Manage Sandbox
```powershell
# Stop VM
Stop-VM -Name <vmname>
# Start VM
Start-VM -Name <vmname>
# Get VM IP
(Get-VM -Name <vmname> | Get-VMNetworkAdapter).IPAddresses
# Delete VM completely
Stop-VM -Name <vmname> -Force
Remove-VM -Name <vmname> -Force
Remove-Item -Path "$env:ProgramData\HyperV-DevSandbox\VMs\<vmname>" -Recurse -Force
```
## Comparison: OrbStack vs Hyper-V
| Feature | OrbStack (macOS) | Hyper-V (Windows) |
|---------|------------------|-------------------|
| Host OS | macOS only | Windows only |
| Setup complexity | Low | Medium |
| Isolation | Full VM | Full VM |
| DNS | `*.orb.local` auto | Manual hosts file |
| SSH | Automatic | Key-based |
| Filesystem sharing | Configurable | Disabled by default |
| Performance | Near-native | Near-native |
| Nested virtualization | Yes | Yes |
## Known Limitations
1. **Windows ADK Required**: Cloud-init ISO creation requires `oscdimg` from Windows ADK
2. **Manual DNS**: No automatic DNS like OrbStack's `*.orb.local`
3. **Key Management**: SSH keys generated per-VM, stored in user's .ssh folder
4. **No Clipboard Sharing**: Disabled for security (can be enabled if needed)
5. **Generation 2 Only**: Uses UEFI, no legacy BIOS support
## Future Improvements
- [ ] Add option for WSL2 (for users who prefer convenience over security)
- [ ] Implement automatic DNS via Windows hosts file or local DNS server
- [ ] Add PowerShell ISO creation without Windows ADK dependency
- [ ] Support for VM templates/checkpoints
- [ ] Integration with Windows Terminal for easy access
- [ ] Optional WinRM configuration for PowerShell remoting

6
config.env.example Normal file
View file

@ -0,0 +1,6 @@
# Copy this file to config.env and fill in your values.
# config.env is gitignored and shared across all VMs you create.
GIT_NAME="guessthepw"
GIT_EMAIL="admin@guessthe.pw"
VNC_PASSWORD="changeme123"

1677
setup_env.sh Normal file → Executable file

File diff suppressed because it is too large Load diff

1076
setup_env_windows.ps1 Normal file

File diff suppressed because it is too large Load diff