Skip to main content

Module sandbox

Module sandbox 

Source
Expand description

The OS sandbox for commands speccoder starts.

Checks, the model’s run_command, the formatter, acceptance tests and MCP servers run code the model may have written. The policy decides which commands run; the sandbox confines what they do:

  • writes only to the workspace, a private temporary directory and the package caches builds need (never the rest of the state directory — approvals live there — and never ~/.cargo/bin);
  • credentials unreadable (~/.ssh, ~/.aws, ~/.cargo/credentials*, …);
  • no network beyond loopback, unless the command is allowed it (exactly, [sandbox] network_allow, or by a prefix in [sandbox] network_allow_prefix) or a person approved it.

The procage library confines every command (module sandbox::procage): Seatbelt on macOS, Landlock, seccomp and, where the kernel allows user namespaces, mounts on Linux. Commands that run to completion are spawned in this process; long-running servers start through the speccoder binary as a helper (__sandbox), which confines itself and becomes the server. Where the host cannot enforce part of the profile, that part is left out by name and the runner says so.

When a sandboxed command fails, its outcome carries what the sandbox refused it (module denials): shown under a failed check, in the next attempt’s digest and in the model’s run_command result. Linux lists refused system calls only; macOS lists every denial it logged, which under heavy load is not every denial.

Modules§

procage
speccoder’s sandbox, confined by procage.

Structs§

Backend
This machine’s sandbox: procage, which confines with Seatbelt on macOS and Landlock and seccomp on Linux. Long-running servers start through the speccoder binary at helper, when there is one (commands that run to completion need none).
Config
[sandbox] in speccoder.toml.
Profile
One command’s confinement.
Sandboxed
A runner that confines every command.
Unenforced
Parts of a profile left out: because the host cannot enforce them (Linux without user namespaces or with an older kernel; the runner’s notice names each), or on purpose (the person’s own commands may write git hooks and agent configuration).

Enums§

Mode
Whether to sandbox.
Network
What a sandboxed command may reach on the network.
Runner
A sandboxed or a plain runner.

Constants§

CACHES
Package caches builds write to, relative to the home directory. Not ~/.cargo as a whole: ~/.cargo/bin would let a test replace cargo.
HELPER_ARG
The helper subcommand (speccoder __sandbox <profile> -- argv…).
HIDDEN
Credentials a command never reads, relative to the home directory.

Functions§

available
Whether this machine can sandbox commands at all (whatever process asks).
backend
The sandbox this machine offers, or why there is none.
contained_at
What [approvals] contained comes to at root, in one line: the commands the sandbox confines run without asking, or why every command that is not a check asks — what init, new and doctor say.
fit
The profile this machine enforces for profile, and a notice for what it leaves out.
helper_main
The helper’s entry (speccoder __sandbox <profile> -- argv…): confines this process and becomes the command; returns only on failure.
parse
Reads [sandbox].
resolve_executable
The executable program runs as in cwd with env: a program with a / against cwd, else the first file of that name on PATH (relative PATH entries against cwd too) — canonicalised; None when there is none. A file without an execute bit is skipped, as execvp skips it: the executable named is the one that runs. What a command’s approval names, and what it is checked against again when it runs.
runner
The runner for commands working in root: sandboxed when configured and possible; otherwise the plain runner and a notice (or, with required, an error).
runner_at
runner with [sandbox] read from the speccoder.toml that governs root.
wrap
argv confined by p through the helper on backend.

Type Aliases§

Wrapped
A command as it will be started: its argv, and the environment to start it with (Profile::private_env) when something confines it.