Agent tools
Capabilities and the sandbox
What an installed or agent-written tool is allowed to touch — 21 declared capabilities, twelve of which have working backends today.
Tools that run as WASM — installed from the registry, or written by the agent — have no ambient authority. They cannot open a file, make a request or run a command unless the capability for it was granted. Every access goes through a checked host import.
This is what makes installing a third-party tool a bounded decision rather than an act of faith.
The capability matrix
Nine of the twenty-one are declared and enforced but have no working backend:
a tool may request them, the gate will hold them, and the host call returns
not_implemented. They are listed here because they appear in the permission
model you will see in a tool's policy file — not because you can build on them
today. All nine are hardware buses and peripherals.
12 of 21 capabilities are implemented. The other 9 are declared and gated by the permission system, and calling one answers not_implemented. They are unfinished work, not features you can use today.
| Capability | Area | Status | What it allows |
|---|---|---|---|
file_read | core | implemented | Read files; 10 MB max per file |
file_write | core | implemented | Write files; counts as destructive |
http_get | core | implemented | HTTP GET; 100 requests per execution, 10 redirects |
http_post | core | implemented | HTTP POST; same limits |
kv_store | core | implemented | Key-value storage; 1000 entries, 1 MB per value |
env_read | core | implemented | Read environment variables, through a denylist and an allowlist that is empty by default |
shell_exec | core | implemented | Run a command from a 15-command allowlist |
logging | core | implemented | Write log lines |
log_read | core | implemented | Read the tool's own log |
telemetry | core | implemented | Counters and timings |
system_info | system | implemented | Hostname, OS, memory, disks |
process | system | implemented | List running processes with pid, name and CPU |
gpio | hardware | not implemented | General-purpose IO pins |
i2c | hardware | not implemented | I2C bus |
spi | hardware | not implemented | SPI bus |
serial | hardware | not implemented | Serial port |
pwm | hardware | not implemented | Pulse-width modulation |
camera | hardware | not implemented | Camera capture |
gps | hardware | not implemented | Location |
mavlink | hardware | not implemented | MAVLink vehicle protocol |
mqtt | hardware | not implemented | MQTT messaging |
The four layers
A capability grant is one of four things standing between a tool and your machine.
1. Compilation isolation. Each tool is built in its own workspace, so no build state is shared between tools.
2. Component validation. The runtime verifies the component's interface when it loads, and a binary scan warns about imports the tool did not declare. The scan is a warning; the runtime gate is what actually enforces.
3. Capability bits. The table above, per tool, checked at every host call.
4. Runtime limits. A CPU budget in fuel, a memory cap, and a wall-clock
timeout per execution (SNAGA_WASM_EXECUTE_TIMEOUT_SECS, 300 seconds by
default) that backstops a tool sitting in a slow host call rather than burning
CPU.
What the guards actually stop
Some specifics worth knowing, because they are the cases that bite:
Requests to internal addresses. http_get and http_post reject private
and cloud-metadata addresses, checking both the URL and what its name resolves
to — and re-checking on every redirect hop. Following redirects without
re-validating is how an external endpoint sends a tool to a metadata service.
Overridable with SNAGA_WASM_ALLOW_PRIVATE_NETWORK=1 and
SNAGA_WASM_ALLOW_METADATA=1 when you mean it.
Reading secrets from the environment. env_read is not blanket access: a
denylist of secret-shaped names, plus an allowlist that is empty by default
and therefore denies everything. The shell child gets a cleared environment for
the same reason.
Shell escapes. shell_exec allows 15 commands, and filters argv for
injection shapes — $(, backticks, ;, &&, ||, redirects, eval, exec,
source, xargs, | sh.
What the sandbox does not claim
The stated design position is that users own their systems and accept the risks on them. The sandbox isolates tools from each other and bounds what they consume. It does not restrict which hosts or files you may reach through a tool you granted the capability to — that is delegated to the OS permissions of the account running Snaga.
One known gap, stated rather than hidden: a redirect to a name that resolves to a private address is not caught by the synchronous redirect check, because the resolving check cannot run inside it. The original URL is resolve-checked, so this narrows the window rather than leaving it open.