Sandbox boundary
fend’s threat model assumes any package may be malicious. This page is the authoritative list of what crosses the host↔VM boundary and what doesn’t.
Filesystem mounts
Section titled “Filesystem mounts”| Host path | VM path | Mode | Notes |
|---|---|---|---|
<project-dir> | /workspace | read-write | VirtioFS. The only place the VM can write that’s also visible on the host. |
~/.fend/cache/npm/ | /root/.npm | read-write | Shared npm cache across projects. |
~/.fend/overlays/<runtime>/ | /usr/local | read-only | Node/Bun/Python runtime, content-addressed. |
Everything else is unmounted. The VM has its own minimal Linux rootfs (busybox
- musl) — it does not see your home directory, your other projects, or any system path on the host.
Paths the VM cannot see
Section titled “Paths the VM cannot see”These don’t exist inside the VM at all:
~/.ssh/— SSH keys~/.aws/— AWS credentials and config~/.gnupg/— GPG keys~/Library/— macOS Keychain database, browser data, cookies, app state~/.config/— shell config, app config, anything you store there~/.zshrc,~/.bashrc,~/.profile— shell init.envfiles outside the project directory- Any other directory under
~/repos/or wherever you keep code - Any other path on the host filesystem
A package running cat ~/.ssh/id_rsa inside the sandbox gets ENOENT. There
is nothing to read because the path was never mounted.
Environment variables — passthrough
Section titled “Environment variables — passthrough”Forwarded to the sandbox automatically:
TERM, LANG, LC_ALL, LC_CTYPE, COLORTERM, NO_COLOR, FORCE_COLOREDITOR, VISUALGIT_AUTHOR_NAME, GIT_AUTHOR_EMAILGIT_COMMITTER_NAME, GIT_COMMITTER_EMAILPlus FEND_PROJECT (the project directory’s basename) is always set inside
the VM.
Environment variables — explicitly stripped
Section titled “Environment variables — explicitly stripped”These are never forwarded, even if set in your shell:
ANTHROPIC_*, CLAUDE_* # Anthropic credentialsAWS_* # AWS credentialsGITHUB_TOKEN # GitHub PATNPM_CONFIG_* # npm registry tokens, authHTTP_PROXY, HTTPS_PROXY # could be abused to redirect installsSSH_AUTH_SOCK # SSH agent socketIf you need to pass a token in, do so explicitly:
fend --env GITHUB_TOKEN=ghp_xxx npm installfend --env-file .env.local npm run seedValues passed via --env or --env-file go into the process environment
inside the VM only. The .env-file itself is parsed on the host and the
values are sent over the vsock control channel — they are never written to
any filesystem the VM can see.
Network
Section titled “Network”The VM has full outbound internet access via the host’s NAT. It needs this to download packages from registries.
What the VM cannot do:
- Listen on a host port directly. Listening sockets are detected by the guest agent and forwarded via the daemon, not by the VM binding to host interfaces.
- Reach the host loopback (
127.0.0.1). The VM’s127.0.0.1is the VM’s own loopback; it cannot reach services running onlocalhoston your Mac. - See your VPN routing, browser cookies, or other network state on the host.
A per-project network policy (allow / deny / log) is planned for the macOS app tier. For now the only knob is “is the VM running” — the alpha CLI does not block outbound traffic.
Resources
Section titled “Resources”Defaults per project VM (override in .fend.toml):
| Resource | Default |
|---|---|
| CPUs | 2 |
| Memory | 2 GB |
| Cold boot | ~800 ms |
| Warm dispatch | ~5 ms |
| Resume from pause | ~100 ms |
| Idle pause threshold | 5 min |
| Idle stop threshold | 30 min |
Per-project state lives in ~/.fend/state/<hash>/. Stale entries (project
directory deleted, or rootfs untouched for 30+ days) are reclaimed
automatically.
When to widen the boundary
Section titled “When to widen the boundary”The boundary is set conservatively because the threat model assumes hostile dependencies. There are legitimate reasons to widen it for a specific command:
- Need a token? Use
--env/--env-file. Per-call, never persisted. - Need Claude Code’s OAuth token for
claude? Usefend claude— it injectsCLAUDE_CODE_OAUTH_TOKENfrom the macOS Keychain, but only for that command. - Need a tool that’s not in the runtime overlay? File an issue — we add tools to the curated overlay set rather than letting the VM reach the host.
Widening the boundary by reaching into ~/ from the VM is intentionally not
supported. That’s the whole product.