Isolating AI commands with --isolate¶
The --isolate flag re-executes bnerd x (TUI) and bnerd mcp-server (MCP) inside a filesystem-isolated environment. Inside the sandbox, the AI's filesystem tools (fs_read_file, fs_write_file, shell_exec, etc.) cannot read or write outside the current working directory plus a small allowlist of credential files.
It composes with --ai-mode (capability boundary). --ai-mode decides which tools the AI can call; --isolate decides where the filesystem-touching tools can reach.
Quick start¶
# Default isolation: workdir + creds + kubeconfig accessible
bnerd --isolate x
# Strict isolation: same, minus ~/.kube/config (so kube_* tools fail)
bnerd --isolate=strict x
# MCP server, isolated
bnerd --isolate mcp-server
# Maximum lockdown for a sketchy local model
bnerd --isolate=strict --ai-mode read-only x
Bare --isolate is equivalent to --isolate=on.
What's mounted¶
Both modes mount the same set, except strict drops ~/.kube/config:
| Path | Mode | Purpose |
|---|---|---|
$PWD | rw | Working directory — the only place the AI can mutate files |
~/.bnerd.yaml | ro | CloudAPI token, AI provider keys |
~/.bnerd/ | rw | Audit log, conversations, reports persist across runs |
~/.gitconfig, ~/.config/git/ | ro | git author/email/signing settings |
~/.config/helm/ | ro | Helm repository config |
~/.gnupg/ | ro | GPG keyring + trustdb (commit signing) |
~/.kube/config | ro | Kubernetes cluster access (omitted in --isolate=strict) |
$SSH_AUTH_SOCK | rw | SSH agent (git push, signed pushes) |
/run/user/$UID/gnupg/ | rw | GPG agent runtime socket |
Everything else under $HOME is hidden by an in-memory tmpfs: ~/.ssh, ~/.aws, ~/.azure, ~/.config/gcloud, ~/.docker, other repos in ~/projects/, your scratchpad in ~/Documents/ — all invisible to the AI.
Network egress is unrestricted in both modes. A future --isolate-allow-net flag will add destination allowlisting.
Runtime prerequisites¶
--isolate picks the first available runtime in this order:
- bubblewrap (
bwrap) — preferred on Linux. ~50ms cold start, no daemon, host PATH inherited (soterraform,ansible, etc. all work). - podman — used when bwrap is unavailable. Rootless by default; clean UID/GID via
--userns=keep-id. - docker — universal fallback.
Run bnerd isolate doctor to see which runtime is selected and what mounts will be applied:
$ bnerd isolate doctor
bnerd isolation diagnostics
===========================
Runtimes (priority order):
bwrap available
podman available
docker available
Selected: bwrap
Mounts for --isolate=on:
bind rw ~/projects/myrepo
bind ro ~/.bnerd.yaml
...
Installing bubblewrap¶
Installing podman / docker¶
Container image (podman/docker only)¶
When the runtime is podman or docker, --isolate runs inside a locally-built image tagged bnerd-isolate:v<bnerd-version>. The first invocation auto-builds it (~2 min). Subsequent runs use the cache.
The image bakes in git, kubectl, helm, jq, yq, curl, wget, make, openssh-client, gnupg2, plus standard coreutils. Not baked in: terraform, ansible, flux, node, npm, python. If your AI workflow needs those, either:
- Use bubblewrap (Linux) — host PATH is inherited, so any host-installed tool works.
- Install them inside
$PWD/.local/bin/— that path is mounted RW so binaries persist. - Submit a PR adding the tool to
pkg/isolate/Dockerfile.isolateif widely useful.
Image management:
bnerd isolate build # build the image now
bnerd isolate prune # remove the cached image
bnerd isolate doctor # show which image (if any) is cached
What --isolate protects against¶
- The AI reading files outside
$PWDand the explicit RO mounts (e.g.~/.ssh/id_rsa, other repos, sibling worktrees). - The AI writing files outside
$PWD(e.g. accidentally creating~/scratch.txt). - A confused or prompt-injected AI exfiltrating arbitrary host files via
web_fetch— those files aren't visible to the AI in the first place. - The AI killing host processes (PID namespace), affecting host IPC/UTS, or escalating privileges (
--cap-drop=ALL,--security-opt=no-new-privileges).
What --isolate does NOT protect against¶
- Network exfiltration of in-scope data. The AI can still POST
$PWD/CLAUDE.mdto attacker.com viaweb_fetch. (v1 limitation; future--isolate-allow-netwill fix this — see the deferred design notes.) - Cluster damage via mounted kubeconfig in non-strict mode.
kube_apply,kube_delete,kube_drainstill run with whatever permissions the kubeconfig grants. Use--isolate=strictto drop the kubeconfig, or--ai-mode read-onlyto bound the AI to read-only operations. - CloudAPI damage.
~/.bnerd.yamlis mounted, so the AI can call destructive CloudAPI tools subject to--ai-mode. - Audit log tampering.
~/.bnerd/audit.logis mounted RW so writes persist across runs, but a determined AI inside isolation canfs_write_fileover it. The log is a debugging tool, not a tamper-evident audit trail. - Forwarded-agent abuse. SSH and GPG agent sockets are forwarded so
git pushandgit commit -Swork. A poisoned model could authenticate as you to any host your keys reach. If this matters, setSSH_AUTH_SOCK=(empty) before runningbnerd --isolate.
Troubleshooting¶
"no isolation runtime found"¶
You don't have bubblewrap, podman, or docker installed. See the Installing bubblewrap and Installing podman / docker sections.
"kubeconfig not found" inside --isolate=strict¶
Expected — strict mode intentionally omits ~/.kube/config. Use plain --isolate if you need cluster access.
terraform: command not found inside --isolate (podman/docker)¶
The image doesn't bake in terraform. Use bubblewrap on Linux, or install terraform into $PWD/.local/bin/ (which is mounted RW).
TUI looks wrong / colors broken¶
Ensure TERM is forwarded (it's on the env allowlist by default) and that you're invoking with a real PTY. Inside an MCP client (which uses stdio), bnerd --isolate mcp-server correctly suppresses TTY allocation.
Image build fails¶
Run bnerd isolate build directly to see the build output. Common causes: no internet (the image fetches kubectl/helm/yq during build), insufficient disk space, or selinux/apparmor blocking the build daemon.
See also¶
--ai-modesafety levels — the capability boundary that composes with--isolate.- Global flags reference — full flag listing.