secure_agent_envs/CLAUDE.md
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

6.6 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-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

  • 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

Testing

There are no automated tests. To test changes:

  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

Security Considerations

  • config.env is chmod 600 and gitignored (stores git name/email only, never VNC password)
  • 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 6 chars), validated to block shell metacharacters, never stored
  • VNC binds to all interfaces (-localhost no) to allow connections from the macOS host — this is intentional for the OrbStack use case and documented in the vnc-start script
  • 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