Policy Model
Five rules. Everything else in the language follows from them.
1. Default deny
Section titled “1. Default deny”An empty policy grants nothing — no files, no network, not even DNS. A fragment’s job is to add reach.
2. Absence never widens
Section titled “2. Absence never widens”This is the one to remember. Leaving something out is always the narrow reading, never the broad one:
- A bare host in
allow_tcpis an error, not an implicit “every port”. - A bare host in an
allow_httplabel means ports 80 and 443, not all 65535. - An
allow_httpblock with an empty body is an error, not “allow everything”.
The reason is code review. If absence widened, this diff would be a privilege escalation that reads like a restriction:
allow_http "api.example.com" { allow_requests ["GET /v1/**"]}3. Deny beats allow, always
Section titled “3. Deny beats allow, always”From any fragment, in any layer, regardless of order or specificity:
fragment A: allow_read ["~/.config"]fragment B: deny_read ["~/.config/secrets"]→ ~/.config/secrets is deniedThere is no override, no priority flag, no “last one wins”.
4. Grants union; only the workspace layer subtracts
Section titled “4. Grants union; only the workspace layer subtracts”base.sbx and every selected fragment compose additively. Two fragments
granting overlapping things is normal and not a conflict.
base.sbx is the exception: nothing may weaken it — not a fragment, and not
your workspace’s .wardcell.sbx, which can add what a profile lacks but never
reopen a base deny. See Layers and Merge Rules.
5. Errors happen at merge time, with a line number
Section titled “5. Errors happen at merge time, with a line number”A malformed rule fails the whole run before anything executes:
fragment 'my-tool' line 12: invalid `allow_tcp` entry in `net` block:`db.internal` needs an explicit port (e.g. `db.internal:5432`, or`db.internal:*` for every port) — a missing port here would silentlygrant every portA typo in a field name is an error too, so allow_red never silently
grants nothing.
The four blocks
Section titled “The four blocks”fragment "example" { fs { ... } # paths net { ... } # hosts, requests, ports env { ... } # environment variables native { ... } # raw backend rules, an escape hatch}Each is documented on its own page. Start with Fragments and the DSL for the file format.