Capabilities & Permissions
saQut runs programs in a deny-by-default sandbox. Your program has no access to the file system, network, or system calls unless you explicitly grant it. This page explains the permission model for practitioners building real programs.
The three capabilities
Section titled “The three capabilities”| Capability | Flag | What it unlocks |
|---|---|---|
| File system | --allow fs |
readFile, writeFile, readDir, exists, remove |
| Network | --allow net |
HTTP requests, sockets (planned 0.9) |
| System | --allow sys |
random, randomRange, env, args, sleep, date::now() |
Multiple capabilities are comma-separated:
saqut run --allow fs,net prog.sqtsaqut run --allow fs --allow sys prog.sqt # repeated flag also worksHow enforcement works
Section titled “How enforcement works”saQut uses a two-layer model (A+B):
Layer A: compile time. When you import a function that requires a
capability (e.g. readFile requires fs), the compiler checks whether the
matching --allow flag was passed. If not, you get a compile error before the
program ever runs.
Layer B: runtime backstop. Even if layer A passes, the VM checks again
before every capability-gated call. This catches edge cases like
caps::drop() removing a capability mid-program. If a call is blocked, the
program throws a catchable E_CAP_MISSING error.
Querying capabilities
Section titled “Querying capabilities”You can ask the compiler which capabilities a program needs without running it:
saqut ir --capabilities prog.sqtOutput:
fs, sysThis scans all imported functions and reports every capability they declare.
caps module
Section titled “caps module”The caps module lets your program inspect and manage its own permissions at
runtime:
import { has, drop } from caps;
if (caps::has("fs")) { string data = readFile("secret.txt"); caps::drop("fs"); // renounce fs for the rest of the program}caps::has(name)returnstrueif the capability is currently activecaps::drop(name)removes it permanently; there is no way to regain it
This lets you follow the principle of least privilege: keep a capability only for as long as you need it.
Why this matters for practitioners
Section titled “Why this matters for practitioners”- Your build script can read source files and write output, but cannot open
sockets;
--allow fsis enough - Your HTTP client program needs network but should not touch the file system;
grant
--allow netonly - A utility that reads environment variables and command-line arguments
only needs
--allow sys
Each program declares exactly what it needs. The compiler and runtime enforce it. There is no ambient authority.
