Policy Schema Reference
This document describes the complete policy YAML schema used by Warden. See Example Policies for a fully-worked example.
Top-level fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
command | []string | No* | CLI-specified via -- | How to start the sandboxed process. If omitted, you must supply the command after -- on the CLI. |
filesystem | Filesystem | Yes | Filesystem access grants. | |
network | Network | Yes | Network egress allowlist. | |
env | Env | Yes | Environment variable passthrough list. | |
limits | Limits | No | Resource limits enforced on Linux. |
* A policy file without command: is valid as long as the CLI supplies the
command via warden run --policy <file> -- <cmd...>.
command
command: ["/usr/bin/node", "server.js"]
The executable should be an absolute path inside the sandboxthe sandbox
binds the parent directory read-only, so only an absolute path is guaranteed
visible. For convenience, warden run (and warden gateway run) also accept
a bare name on PATH (npx, uvx, node) and resolve it via LookPath at
launch, failing closed when the name is not found. Prefer the absolute path
in checked-in policies so the grant is explicit and reproducible.
Values after the executable are passed as-isrelative paths here are
resolved against the policy file's directory by ResolvePaths.
filesystem
filesystem:
read: ["./data/cache"]
write: ["./output"]
Each entry is a path (relative to the policy file, resolved by
ResolvePaths). After resolution:
readpaths are bind-mounted read-only.writepaths are bind-mounted read-write.- Paths inside the runtime base (
/usr,/lib64) cannot be granted write — that would make part of the system writable and widen the sandbox. - A path listed in both
readandwriteis coalesced to a singlewritegrant at load time (Normalize), since a write grant already subsumes reads underneath it. The backends keep a fail-closed ambiguity check for policies constructed programmatically without going throughLoad.
Validation rules:
- Paths must not be empty.
- After resolution, paths must be absolute.
- Paths resolving to the filesystem root (
/) are rejected. - Relative paths are resolved against the directory containing the policy file, not the current working directory.
EnforcedYes. The Linux (bwrap) backend mounts only these paths; everything else is invisible to the sandboxed process.
network
network:
allow:
- "api.github.com"
- "10.0.0.5"
A list of hostnames or IP literals the sandboxed process may reach. Ports are not part of the grantthe egress proxy forwards all ports for an allowlisted host.
Validation rules:
- Entries must not be empty.
- Must be a bare hostname or IP literalpaths (
/foo), query strings (?q=1), fragments (#anchor), and colons (interpreted as ports) are rejected. - Hostnames must not exceed 253 characters; each label must be 1–63 chars, alphanumeric or hyphen, and must not start or end with a hyphen.
- IPv6 literals are accepted via
net.ParseIP.
EnforcedLinux only. The sandbox gets a private network namespace with no default route; all external traffic goes through the egress proxy which checks this allowlist. On macOS the Seatbelt backend denies all network except loopback to the proxy bridge; the proxy enforces the list. Docker runs with
--network noneand similarly uses the proxy bridge.
See Architecture – Egress Proxy for the proxy design.
env
env:
allow:
- "GITHUB_TOKEN"
- "NODE_ENV"
A list of environment variable names to forward from the parent process. Values are never stored in the policy filethey are read from the parent at runtime. An empty allowlist results in an empty environment for the sandboxed process.
Validation rules:
- Variable names must not be empty.
- Names must not contain spaces, tabs, newlines, or
=characters.
EnforcedAll platforms.
envfilter.Filterselects only the allowlisted names fromos.Environ()before spawning the child.
Security note: If you pass
HOMEthroughenv.allow, the sandboxed process sees your real home directory. Combined with afilesystem.readgrant for~/.ssh, this leaks your SSH keys. See Security Review for details.
limits
limits:
memory_mb: 512
timeout_s: 300
| Sub-field | Type | Required | Default | Description |
|---|---|---|---|---|
memory_mb | int | No | 0 (no limit) | Resident memory cap for the entire process tree. Sampled every 25 ms; exceeded processes receive SIGTERM then SIGKILL after 750 ms. |
timeout_s | int | No | 0 (no limit) | Wall-clock timeout. Breach triggers the same SIGTERM → SIGKILL sequence. |
Validation rules:
- Values must not be negative.
memory_mbmust not overflow when converted to bytes.timeout_smust not overflow atime.Duration.
EnforcedLinux (bwrap) backend. macOS and Docker backends do not currently enforce these limits; the values are parsed for schema compatibility but silently ignored. No CPU throttling is available on any platform.
Cross-reference
- For a complete working policy, see Example Policies.
- For backend-specific enforcement details, see Architecture – Sandbox Backends.
- For security implications of each section, see Security Review.