DEV Community

Cover image for The sandbox catches the input you forgot to declare
VX
VX

Posted on Edited on Originally published at vznjs.github.io

The sandbox catches the input you forgot to declare

Forget to declare an input and the cache can serve a stale hit. The
sandbox fails the task instead, and prints the fix.

check: {
  exec: {
    command: 'cat src/index.ts notes.md',
    sandbox: { allow: { read: ['src'] } },
  },
  inputs: { files: ['src/**'] },
  cache: { outputs: { files: [] } },
}
Enter fullscreen mode Exit fullscreen mode
$ vx run packages/a#check
┌─ packages/a#check > $ cat src/index.ts notes.md
export const a = (n: number) => n * 2
export const extra = 1
cat: notes.md: No such file or directory
├─ SANDBOX VIOLATIONS (1) ────────────────────────────────────

openat(notes.md) = -1 ENOENT  [.../packages/a/notes.md]

fix: exec.sandbox.allow: { read: ['notes.md'] }
and, if the output depends on them, inputs.files: ['notes.md']

└─ packages/a#check ── (109ms) failed (exit 1, 1 sandbox violation)
Enter fullscreen mode Exit fullscreen mode

Inside the sandbox an undeclared file does not exist. A failed task is
never cached, so the mistake cannot reach the cache.

A sandboxed task starts with nothing

sandbox: {} reads nothing in the workspace, writes only its TMPDIR
and has no network. Most tasks start with sandbox: { allow: { read:
['.'] } }
.

~/.ssh and ~/.npmrc stay closed unless a grant names them.

Grant What it opens
read paths or globs: project-relative, absolute or ~
write the same; a write grant is readable too (.tsbuildinfo)
network true, or domains with wildcards, through one proxy per run
localBinding ports a test server listens on
unixSockets unix sockets
systemInfo named system values
gitConfig writing .git/config, for this task only
machLookup macOS services
pty a terminal, on macOS

Those are the keys of allow. deny blocks network domains for the whole run. ignore hides a known,
harmless denial. Each task lists its own grants, with no defaults.

Grant no wider than your inputs

diagram

vx links neither to the other, so the violation is judged against the
grants alone. Grant read: ['src', '.eslintrc'] and every failure is an
input you missed.

The fix line never offers ~/.ssh or a .env file.

What it costs

diagram

linux x64, 4 cores, root in a container · vx 0be0367 · 2026-10-23

Turn it on where inputs matter: in CI, and before a task goes to
remote execution.

Linux and macOS

Linux needs bwrap, socat and rg, plus strace for the report.
macOS uses seatbelt. Windows runs it through WSL.

diagram

The 16 are suites a sandbox cannot host, Docker services and checks that
drive the sandbox themselves. Guide: Sandboxing
tasks
.

More at vznjs.github.io/vx.


Originally published on the vx blog. vx is open-source (MIT) task orchestration with a build cache: vznjs.github.io/vx · GitHub.

Written with AI assistance.

Top comments (0)