Run Claude Code and Codex in hardened sandboxes on macOS — one isolated container per agent,
inside a dedicated Apple container machine. Everything risky is opt-in.
Documentation ·
Install ·
Quickstart ·
Security model
The agent operates freely inside its sandbox; the sandbox is the boundary. Host access, shared auth, SSH, AWS credentials, and Docker access all stay off until you flip a flag.
macOS host (berth CLI / TUI / desktop app)
-> Apple container machine "berth" (hardened)
-> Docker daemon (userns-remap)
-> one container per agent
- Real isolation, not editor policy. Read-only rootfs,
cap-drop ALL,no-new-privileges, resource limits, per-agent bridge networks with egress guardrails — three boundaries deep (host → VM → container → container). - Safe by default. No SSH, no shared auth, no host credentials, no Docker access unless you opt in — and hard policy rules can deny risky spawns entirely.
- Built for daily work. tmux-backed sessions you can reattach, steer, diff, review, checkpoint, and turn into PRs — from the CLI, a k9s-style TUI, or a native macOS app.
- Scales past one agent. Fleet manifests for parallel fan-out, pipelines with dependencies, judge stages that pick the best of N candidates, scheduled runs, and a JSON-RPC state server.
Install Apple container from the signed pkg, then:
brew tap 0x666c6f/tap
brew install berth
berth setup # creates the VM, hardens it, builds the image
berth diagnose # verify everything is greenFrom source: git clone, make build-all, add bin/ to your PATH. Migrating from safe-agentic? See the migration notes.
# Quick start with smart defaults
berth run https://github.com/myorg/myrepo.git "Fix the failing CI tests"
# Full control
berth spawn claude --ssh --repo git@github.com:myorg/myrepo.git --prompt "Fix the failing CI tests"Then work the loop:
berth status --latest # blocked / working / done / idle / exited
berth peek --latest # snapshot the live terminal
berth steer --latest "keep the fix narrow"
berth diff --latest # what changed
berth review --latest # AI review pass
berth pr --latest # push branch + open a PR
berth stop --latestMultiple agents? berth tui for a live dashboard, berth inbox for what needs attention, or the desktop app for embedded terminals and native notifications.
berth fleet fleet.yaml # parallel agents from one manifest
berth pipeline pipeline.yaml # staged execution with depends_on + judge stages
berth pr-review # one-shot dual Claude+Codex PR review
berth cron add nightly "daily 02:00" pipeline review # scheduled runs
berth spawn claude --worktree --prompt ... # work on your local checkout (opt-in)If you only need a public repo and a prompt, don't add flags you don't need. Each widener is explicit:
| Flag | Why you'd use it | What it widens |
|---|---|---|
--ssh |
private repos, pushes | repo access through your SSH agent |
--reuse-auth |
avoid re-auth | shared agent auth volume |
--reuse-gh-auth |
gh inside containers |
shared GitHub auth volume |
--seed-auth |
skip first login | one-shot copy of host Claude/Codex auth |
--aws <profile> |
infra work | AWS API access |
--docker |
build/test containers | DinD sidecar |
--docker-socket |
full Docker control | direct VM daemon access |
--network <name> |
custom connectivity | leaves managed network policy |
--worktree |
local checkout in the sandbox | VM home-mount boundary (trade-off) |
Full threat model, defaults, and supply-chain notes: Security.
| Installation | toolchain, VM setup, migration |
| Quickstart | first agent in five minutes |
| Guides | spawning, managing, review & ship, worktrees, fleets, automation, TUI, desktop app, configuration |
| CLI reference | every command and flag |
| Architecture | the three isolation boundaries |
| Security | defaults, wideners, threat model |
- containers persist after the agent exits;
berth attachrestarts stopped containers berth cleanupkeeps auth volumes;berth cleanup --authis the full reset- a macOS reboot resets the host NAT the VM needs —
berth vm startre-applies it BERTH_VM_NAME,BERTH_CONFIG_HOME,BERTH_STATE_HOMErelocate the VM/config/state