Run your coding agents (Claude, Codex, ...) inside isolated, disposable Anka macOS VMs.
Crypt clones a prepared base VM into a shadow clone, launches the agent in
unattended ("YOLO") mode, and keeps the clone running between sessions so
agent state is preserved. Pass --destroy to delete after a run, or run
crypt destroy later. By default the guest cannot reach your host filesystem.
Pass --mount only when you need the agent to edit files in the current
directory β that shared path is writable from the VM and changes apply on the
host, so mount only directories you are willing to expose.
host Anka VM (kept after run)
βββββββββββββββββ clone βββββββββββββββββββββββββββββββββ
β crypt claude β βββββββββββΆ β claude --dangerously-skip-... β
β --mount β βββ mount ββΆ β /Volumes/My Shared Files/$CWD β
βββββββββββββββββ βββββββββββββββββββββββββββββββββ
Agents run far more smoothly when they aren't stopping to ask permission for every
file edit or shell command. The flags that unlock that (--dangerously-skip-permissions,
--dangerously-bypass-approvals-and-sandbox) are genuinely dangerous on your host.
Crypt makes them safe by confining the agent to an ephemeral VM.
- Anka Virtualization. Any recent version works; 3.9 or newer is required
when using
--mount(host directory mounting was added in Anka 3.9.0). - Apple Silicon is required for
--mount. Directory mounts are not supported on Intel. - Anka Enterprise is required for
--no-localnetwork isolation. - A base Anka VM that you have prepared with the agent installed and authenticated.
brew tap veertuinc/crypt https://github.com/veertuinc/crypt
brew trust veertuinc/crypt
brew install --cask cryptHomebrew's short tap name (veertuinc/crypt) expects a repo named homebrew-crypt; the
explicit URL tells it to use this repository instead.
Or download the latest release (macOS only; installs to /usr/local/bin, or set INSTALL_DIR):
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/veertuinc/crypt/edge/scripts/install.sh)"Or build from source (requires Go 1.25+):
go install github.com/veertuinc/crypt@latestCrypt does not download VM templates. You create and prepare your own base VM, and Crypt clones it for each run.
-
Create the base VM (name it
crypt-base, or anything and pass--vmlater):anka create crypt-base latest
-
Boot it and install + authenticate the agent(s) you want to use inside it:
anka start crypt-base anka run crypt-base zsh -lc '/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" && brew install node' anka run crypt-base zsh -lc 'npm install -g @anthropic-ai/claude-code' # Optional: set the model to use (default is latest model from anthropic) anka run crypt-base bash -c "echo 'export ANTHROPIC_MODEL=\"claude-sonnet-4-5-20250929\"' >> ~/.zprofile" anka run crypt-base zsh -lc 'npm install -g @openai/codex' # Log in to each agent once so credentials are baked into the base VM: anka run crypt-base zsh -lc 'claude' # follow the login prompts anka run crypt-base zsh -lc 'codex' # follow the login prompts anka stop crypt-base
Note
Interactive sessions (crypt claude with no prompt) connect over SSH so the
agent gets a real terminal. Crypt generates a dedicated SSH key on first use
(~/.config/crypt/id_ed25519) and authorizes it in the clone automatically;
you only need Remote Login enabled in the base VM. Crypt logs in as the
anka user by default β override with CRYPT_SSH_USER.
- On first setup, harden network access on the base VM (recommended; requires Anka Enterprise). Clones inherit this setting:
Important
--no-local is only available with an Enterprise or Enterprise Plus license.
anka modify crypt-base network --no-localEvery clone Crypt makes inherits this prepared state, so you only authenticate once.
Two approaches:
- Use
crypt claudeto run the agent in interactive mode. - Run
crypt claude "fix the UI bugs from the make test output"for non-interactive mode.
β― crypt claude 'who are you?'
crypt: VM name is crypt-clone-1
crypt: cloning crypt-base -> crypt-clone-1
crypt: starting crypt-clone-1
crypt: SSH: ssh anka@192.168.64.8
crypt: VNC: open vnc://anka@192.168.64.8
crypt: launching claude (may take a while for VM to boot)
I'm Claude, an AI assistant built by Anthropic. In this context, I'm running as Claude Codeβa tool designed to help you with software engineering tasks like writing code, debugging, refactoring, and understanding codebases.
I can read and edit files, run shell commands, search through your code, create commits, and work with various development tools. I have access to your working directory at `/Users/anka` and can help you with whatever programming tasks you need.
Is there something specific you'd like help with?
crypt: kept VM crypt-clone-1 running (crypt destroy when done)
β― crypt claude --mount "do you see the mount in the VM under /Volumes/My Shared Files"
Yes, I can see the mount! It's visible at `/Volumes/My Shared Files` and is mounted using **AppleVirtIOFS** (Apple's virtualization filesystem for sharing between host and VM).
**Mount details:**
- Device: `/dev/disk0`
- Mount point: `/Volumes/My Shared Files`
- Filesystem: AppleVirtIOFS
- Size: 926GB total, 789GB used, 137GB free
- Contains the `crypt` directory we're currently working in
The mount is working and accessible.crypt claude --mount "keep going" # takes the current folder where we're executing the command and mounts that temporarily into the VM for the duration of the command
crypt claude # interactive; VM kept until crypt destroy
crypt --name backend claude --mount "add endpoint" # separate named VM for another project
crypt claude --destroy "one-shot" # delete when the run ends
crypt destroy # delete the kept VM for this directory
crypt --name backend destroy # delete a named VMFlags:
| Flag | Default | Description |
|---|---|---|
--name |
(auto) | Explicit clone VM name (crypt-clone-1, crypt-clone-2, β¦ when omitted; same directory reuses its clone) |
--vm |
crypt-base |
Base Anka VM to clone for the sandbox |
--cpu |
0 |
Override vCPU core count (0 = use the VM setting) |
--memory |
0 |
Override RAM in MB (0 = use the VM setting) |
--mount |
false |
Mount the current directory into the VM (exposes that path on the host) |
--destroy |
false |
Delete the clone when the run ends (default: keep until crypt destroy) |
--no-local |
false |
Block VM-to-VM and VM-to-host network on the clone (Anka Enterprise) |
Unknown flags (e.g. --model, --resume) are forwarded to the agent unchanged.
- Verify Anka is installed and the base VM exists (Anka 3.9+ when using
--mount). anka clone <base> crypt-clone-Nβ an instant shadow clone (lowest free number; printed on stderr).- With
--no-local,anka modify <clone> network --no-localβ block VM-to-VM and VM-to-host network traffic (requires Anka Enterprise; usually set once on the base VM instead). anka startthe clone (applying any--cpu/--memoryoverrides first).- With
--mount,anka mount <clone> <cwd>β your directory appears at/Volumes/My Shared Files/project1in the guest. The agent can read and write that path; changes are visible on the host. Only mount a directory you trust the agent with. - Launch the agent with its unattended-mode flags injected. For Claude Code,
Crypt also pre-trusts the guest workspace in
~/.claude.jsonso the "Do you trust this folder?" dialog is skipped. A task prompt (crypt claude "fix the UI") runs unattended viaanka run; an interactive session (crypt claude) connects overssh -tso the agent gets a real terminal for its full TUI. - On exit (including Ctrl-C), the clone stays running and is kept on disk unless
you passed
--destroy, which deletes it. Remove kept clones withcrypt destroy(orcrypt --name <vm> destroy). If--mountis added to an already-running kept clone, Crypt unmounts that temporary host path after the command finishes. Your base VM is never modified.
Important
These features require an Enterprise or Enterprise Plus license.
--no-local
blocks VM-to-VM and VM-to-host network communication. Enable it once when you
prepare your base VM (recommended β clones inherit the setting):
anka modify crypt-base network --no-localOr pass --no-local on a Crypt run to apply it to that clone only.
For tighter control, bake IP filtering rules into your base VM before Crypt clones it. Rules are evaluated in order; the first match wins. Example β block local traffic and deny everything else:
cat <<'EOF' | anka modify crypt-base network -f-
block local
block any
EOFYou can also set global host rules with anka config net_filter, or embed
per-VM rules so clones inherit them. See Anka's
Advanced Security Features
for the full rule syntax and additional options (including TUN/WireGuard on the
host for routing all VM traffic through a VPN).
When using --mount, Anka shares directories via Apple's virtiofs implementation
on macOS. That stack has a known caveat: edits made on the host after mounting
may appear stale inside the guest. This is an Apple platform limitation β not a
Crypt bug. In practice it does not affect the common workflow β the agent edits
files inside the guest, and those writes propagate back to the host correctly.
If you edit files on the host mid-session, prefer creating new files or atomically
replacing them (write a temp file, then mv over the target) so the guest picks
up the change.
