Status: engine and the switch are in; the blocked-write card is not yet. The boundary
(host-side write checks + macOS Seatbelt wrapping), the fail-closed rule, session-preference
persistence and the composer lock chip all work today (with unit tests and a real-machine
check). What is still missing is the card that offers “allow once / remember this
directory” when a write is blocked — for now a block surfaces as a tool error the model
can act on. The default is still full-access.
Off by default on purpose: the biggest risk of a sandbox is not bypass, it is breaking normal work for no visible reason. Collect the false-positive list before turning it on by default.
The three modes
The
workspace-write allow set = workspace + write roots you recorded in
.kova/permissions*.json + platform temp directories + a toolchain cache
allow-list (~/.bun/install/cache, ~/.npm, ~/.cache, ~/.cargo/registry,
~/Library/Caches, ~/Library/pnpm, ~/.yarn/berry/cache, ~/go/pkg/mod,
~/.gradle/caches, ~/.m2/repository, …). Miss one entry and installs start
failing — that is the most common “it broke for no reason” case.
Two fixed rules:
- Reads stay open. read-only means “cannot write”, not “cannot look”; it is not confidentiality isolation.
.env/.env.*/*.pem/*.keynever land on disk (denyWrite, hard refusal without a prompt).
Where the boundary is enforced
The order is deny → allow → refuse. Refusals come back as tool errors that
tell the model what to do instead (write inside the workspace, or ask the user
to add a write root).
Fail closed
If the sandbox cannot start (missingripgrep, unsupported platform, profile
generation failed), the command is not executed and the error names the
reason and the way out. Never a silent unsandboxed fallback: “thought it was
isolated when it was not” is far worse than “this step failed”.
How it relates to the other two mechanisms
- Approval decides whether you are asked;
- AI review lets the model decide instead of you;
- The sandbox decides how far an allowed call can reach.
How to switch it
In the composer toolbar, to the right of the permission picker, there is a lock: closed with a shield = workspace isolation, a blue closed lock = read-only, open lock = no sandbox. Click it to switch; the choice is a session preference (survives reloads) and new sessions follow your last pick.full-access is the default, so you have to switch
once to actually enable isolation.
Known limits
- macOS only for subprocess isolation in this version; other platforms report an honest error instead of pretending to isolate.
- MCP server processes are not wrapped yet;
write/editand bash are. - No network policy yet (file isolation only).
- The sandbox cannot read intent — it only looks at paths. To stop it from refusing something legitimate, add that root to the write-roots list (the same list “Workspace-write” uses).
Next
The sandbox and its three neighbours: session mode, permission presets, automation policy.
