Technical Briefing: vibe

REPO SUMMARY

vibe (https://github.com/moses-y/vibe) is a single-binary tool that spawns a Linux virtual machine on macOS to sandbox LLM agents. The repository contains 10 files: 6 at root, 3 in src/, and 1 in .github/. Primary build system is Cargo (Rust). CI runs via GitHub Actions. No Dockerfile; license file present; lockfile committed; no detected secrets.

THE PROBLEM

LLM agents operating without sandboxing can read and modify files outside the intended project directory, creating security and compliance risks. The author experienced this firsthand when running codex without --yolo and observing it accessing files beyond the title directory. Virtualization offers stronger isolation than containers or the macOS sandbox framework, but existing solutions require significant configuration.

WHAT THIS DOES

vibe spins up a minimal Debian Linux VM on ARM-based Macs (macOS 13+). On first run it downloads a base image; subsequent starts boot in approximately 10 seconds on M1 hardware. The VM mounts project directories and common developer tooling (.cargo/registry, .m2, .codex, .claude, etc.) as read-write volumes. A help-text example shows mounts for /Users/dev/work/my-project → /root/my-project and similar paths for caches and registries. The binary is under 1 MB; the entire implementation resides in a single ~1200-line Rust file with only objc2 and lexopt as dependencies.

HOW IT IS WIRED

Execution starts at main in src/main.rs:118, which reaches 18 functions and is called from 1 place. The internal call graph contains 28 resolved call edges between self-functions. Key entry points and their reach:

  • parse_cli (src/main.rs:291) — reaches 1 function
  • ensure_default_image (src/main.rs:580) — reaches 18 functions
  • run_vm (src/main.rs:1037) — reaches 18 functions, called from 2 places
  • create_vm_configuration (src/main.rs:829) — reaches 3 functions

Widest blast radius functions: run_vm and ensure_default_image each reach 18 functions; create_vm_configuration reaches only 3. Control flow in src/main.rs exhibits max indentation depth of 15 and 1131 code lines, making it hard to hold in one mind; a change here ripples widely.

Outside the repository, the tool invokes qemu and debootstrap to provision the VM; it reads/writes host filesystem paths and interacts with macOS window management. No external API calls beyond the initial Debian image download.

HOW TO USE IT

Install: Download the latest macOS ARM64 binary from GitHub Actions releases:

curl -LO https://github.com/lynaghk/vibe/releases/download/latest/vibe-macos-arm64.zip
unzip vibe-macos-arm64.zip
mkdir -p ~/.local/bin
mv vibe ~/.local/bin
export PATH="$HOME/.local/bin:$PATH"

Or via cargo install --locked --git https://github.com/lynaghk/vibe.git (requires Rust).

Run: vibe [OPTIONS] [disk-image.raw]. Options include --help, --version, --no-default-mounts, and --mount host-path:guest-path[:read-only | :read-write]. First run requires network access to pull the base image.

Configuration: No config files or environment variables are required; mounts are specified inline via --mount flags. Default mounts include .git, .vibe project subfolder, and common developer directories.

REAL-WORLD USE

A developer working with an LLM agent can invoke vibe from their project directory to give the agent a confined environment. With --yolo the agent can install/remove tools without prompting; without it, every command requires approval. The sandbox prevents the agent from accessing host files outside the explicitly mounted paths. Example workflow:

cd my-project
vibe --mount ~/.cache:/root/.cache:read-write

The agent sees only the project directory and explicitly shared paths, not the full host filesystem.

CODE HEALTH & ISSUES

Five findings from static analysis, ranked by severity:

  • [HIGH] Pin third-party GitHub Actions to a commit SHA — .github/workflows uses dtolnay/rust-toolchain@stable; a tag can move, so the action running with repository secrets executes whatever its owner last pushed.
  • [MEDIUM] Enable Dependabot or Renovate — 1 manifest present, no update bot configured; published advisories go unpatched until manual audit.
  • [MEDIUM] Gate pull requests on a dependency vulnerability scan — no dependency scan in CI; this is the primary gate that would catch a known-vulnerable package before build.
  • [MEDIUM] Set persist-credentials: false on checkout — .github/workflows/release.yml checkout retains the token; later steps (including dependency installation) can read pushable credentials without an explicit token being passed.
  • [LOW] Set timeout-minutes on workflow jobs — 1 workflow declares no job timeout; a wedged step runs to the six-hour platform default.

Additionally, the codebase has no test files detected; the single src/main.rs file at 1131 lines exhibits deep nesting (max depth 15) and cognitive overhead from oversized file size.

THE BOTTOM LINE

vibe delivers a functional, zero-configuration Linux VM for sandboxing LLM agents on ARM Macs, with sub-10-second boot and a sub-1 MB binary. The single-file Rust implementation using only objc2 and lexopt keeps dependencies minimal. However, the codebase suffers from an oversized main module with deep nesting, no test coverage, and several SDLC gaps: unpinned GitHub Actions SHAs, missing dependency scanning, and unguarded checkout credentials. Teams seeking a lightweight sandbox for agent workflows will find vibe practical, but should address the hygiene findings before integrating into regulated environments.