Providers

Tart Provider

Tart Provider

Read this when you:

  • choose provider: tart (aliases local-tart, macos-vm);
  • want local macOS VMs on Apple Silicon through Cirrus Labs tart;
  • change internal/providers/tart.

Tart is a local SSH-lease provider. Crabbox drives the tart CLI on an Apple Silicon Mac, clones a macOS VM from an OCI base image, configures CPU/memory/disk, starts the VM headless, injects an SSH key via tart exec, syncs the checkout over SSH, runs commands through the normal Crabbox SSH executor, and deletes the VM on stop.

The provider is local only. It never uses the coordinator or cloud credentials.

Targets: macOS.

Hosts: Apple Silicon Macs with tart installed (brew install cirruslabs/cli/tart).

#Optional live smoke

Run the guarded local smoke when Tart is installed and the configured macOS base image is available or can be downloaded:

CRABBOX_LIVE=1 CRABBOX_LIVE_PROVIDERS=tart scripts/live-smoke.sh

The smoke creates one short-lived Tart VM, waits for SSH readiness, syncs the current checkout, runs the shared live-smoke command, prints recent history/log evidence when available, then stops and deletes only the VM it created. It uses --ttl 30m --idle-timeout 5m because the first run may need to pull and boot a macOS base image, and it follows the same cleanup path as normal crabbox stop --provider tart.

#Configuration

CLI flags:

FlagDefaultDescription
--tart-imageghcr.io/cirruslabs/macos-sequoia-base:latestOCI base image to clone
--tart-cpu4Guest CPU count
--tart-memory8192Guest memory in MB
--tart-disk(clone default)Guest disk size in GB; only applied when explicitly set

YAML (.crabbox.yaml):

tart:
  image: ghcr.io/cirruslabs/macos-ventura-base:latest
  user: admin
  workRoot: /Users/admin/crabbox
  cpus: 4
  memory: 8192
  # disk: 80  # only set to resize beyond the base image default

Environment variables: CRABBOX_TART_IMAGE, CRABBOX_TART_USER, CRABBOX_TART_PASSWORD, CRABBOX_TART_WORK_ROOT, CRABBOX_TART_CPUS, CRABBOX_TART_MEMORY, CRABBOX_TART_DISK.

CRABBOX_TART_PASSWORD (or tart.password in the mode-0600 user config printed by crabbox config path) is the guest account password the local WebVNC viewer uses for macOS Apple/ARD authentication. It defaults to admin (the cirruslabs base-image account) and is only handed to the local browser viewer over an authenticated localhost endpoint — never written to the guest. Do not put tart.password in repo-local crabbox.yaml or .crabbox.yaml. There is intentionally no CLI flag for it, which keeps the password out of shell history and process metadata.

#How it works

  1. tart clone <image> crabbox-<slug> creates a new VM from the base image.
  2. tart set crabbox-<slug> --cpu N --memory N configures resources (disk size is only resized when --tart-disk is explicitly set).
  3. tart run crabbox-<slug> --no-graphics starts the VM headless.
  4. tart ip crabbox-<slug> polls for the guest IP (DHCP, typically ~10s).
  5. tart exec crabbox-<slug> bash -c "..." injects the SSH public key.
  6. Crabbox waits for SSH readiness, then syncs and runs commands normally.
  7. For --desktop leases, tart exec turns on the guest's built-in macOS Screen Sharing (native VNC on port 5900). No VNC password is provisioned — authentication uses the guest account's own credentials.
  8. tart stop + tart delete on release.

#Desktop / VNC

Lease with --desktop to get a visible macOS session:

crabbox warmup --provider tart --desktop
crabbox webvnc --provider tart --id <lease-id>   # shared portal, or local fallback without coordinator login
crabbox screenshot --provider tart --id <lease-id> --output desktop.png

crabbox webvnc runs a host-side bridge to the guest's Screen Sharing port; the guest needs no noVNC/websockify tooling. With an authenticated coordinator login, Crabbox registers the Tart lease and presents it inside the same portal chrome and controls as Linux and Windows. The registration follows the Tart lease until crabbox stop or normal coordinator expiry and never grants the coordinator authority to delete the VM. Without coordinator auth, Crabbox keeps the self-contained mode-0600 localhost viewer as an offline fallback. crabbox screenshot uses the same locally configured account credentials for noninteractive capture. noVNC authenticates via macOS Apple (ARD) auth with the lease account credentials. Prefer a native VNC client instead? Tunnel and connect directly:

ssh -i <lease-key> -o GatewayPorts=no -L 127.0.0.1:5900:127.0.0.1:5900 admin@<lease-ip>
open vnc://127.0.0.1:5900    # macOS Screen Sharing, or any VNC client

The VM still starts with --no-graphics (the local display is not needed); for --desktop leases the provider turns on the guest's built-in macOS Screen Sharing (com.apple.screensharing). Authentication uses the guest account's own credentials (macOS user auth, e.g. admin/admin on the cirruslabs base image) — crabbox provisions no separate VNC password and passes no credential to the guest.

Remote control plane (controller → Mac → guest). When crabbox runs on the Mac over SSH from another machine, the guest's VNC port isn't directly reachable from the controller — forward it *through* the Mac to the guest's tart IP:

# on the controller (the guest IP is printed by `crabbox warmup`):
ssh -o GatewayPorts=no -L 127.0.0.1:5900:<guest-tart-ip>:5900 <user>@<mac-host>
open vnc://127.0.0.1:5900    # native VNC client on the controller

Exposure boundary: macOS Screen Sharing binds all guest interfaces, so the VNC server is reachable at the guest's address on the tart host network (not localhost-only), gated by account authentication. tart's network is host-local (only the Mac can reach the guest), so the effective boundary is "account-authenticated VNC, reachable from the tart host." The SSH tunnels above keep the viewer side on 127.0.0.1.

> The browser viewer is a host-side bridge (the guest needs no noVNC/websockify). With coordinator auth, webvnc status, reset, and daemon use the shared portal model. Without coordinator auth, remote operators can still forward the printed localhost web port and copy/open the mode-0600 handoff file while the bridge is running.

#Not yet supported

  • Shared-directory mounts (tart run --dir; needs explicit host-mount config).
  • Checkpoint/fork (tracked as a separate follow-up PR).