Three ways to build a policy
From a dict — the model validates it (including every constraint’s grammar):PolicyBuilder — fluent, and C(...) gives you type-checked
constraints instead of hand-written strings:
C covers every operator: <= < > >= == !=, .is_in([...]), .not_in([...]),
.count(), and cross-field comparisons (C("args.max") >= C("args.min")). Each
constraint is validated the moment you write it, so a typo raises at that line —
not later at enforcement.
Role-aware, with RolePolicyBuilder — produces a PolicySet:
Gate network egress
net_allow and net_approve are builder sugar for the egress
plane. They render a host/scheme/port allowlist into ordinary
net.http_request constraints, so an egress rule enforces the same way in both
the pydantic and WASM engines.
subdomains matches the apex and any child (example.com and *.example.com).
A host restriction is required: pass hosts=, subdomains=, or any_host=True.
Calling net_allow() with only a scheme or port filter raises, because it would
authorize every host.
Restrict file tools to paths (file_scope)
The file tools read_file, write_file, edit_file (argument file_path),
glob and grep (argument path) accept a file_scope that limits which paths
they reach:
tools.<name>.file_scope.denied_pathswins: a path matching it is denied even iffile_scope.allowed_pathsmatches too.- With
file_scope.allowed_pathsset, a path that matches none of its patterns is denied. - A call without the path argument is denied.
Unit-test a policy
Theassert_* helpers evaluate a policy the same way the runtime enforces it:
PolicySet, pass role=:
The builder and
C emit the exact constraint strings the YAML parser
accepts, so a policy built in code enforces identically to the same policy in
YAML — there is only one grammar.