Policy reference
A policy is TOML. Top-level keys plus an ordered list of [[rules]]. The first
matching rule wins; otherwise default.
Top level
| Key | Type | Meaning |
|---|---|---|
default | "allow" | "deny" | "require_approval" | Decision when no rule matches. |
require_identity | bool | Deny any call without a verified, accountable token. |
A rule
[[rules]]
tool = "wire_funds" # exact, prefix* , or *
decision = "require_approval" # allow | deny | require_approval
reason = "large transfers need a human" # recorded in the audit
require_role = "finance.approver" # RBAC gate
require_relation = { relation = "owns", resource_arg = "account" } # ReBAC gate
when = { arg = "amount", op = "gt", value = 1000 } # condition (see below)
max_per_run = 5 # per-run budget
| Field | Meaning |
|---|---|
tool | Match: exact name, prefix* wildcard, or * (all). Case-exact. |
decision | allow / deny / require_approval. |
reason | Human-readable, recorded in the audit entry. |
require_role | Token must carry this role (implies require_identity). |
require_relation | Token must hold relation@<value of resource_arg>. |
when | Condition tree that must hold for the rule to apply. |
max_per_run | Cap on invocations per run (reserved atomically). |
Conditions (when)
Leaf condition:
when = { arg = "amount", op = "gt", value = 1000 } # a tool argument
when = { field = "subject:region", op = "eq", value = "EU" } # a signed token attr
when = { field = "resource:classification", op = "eq", value = "public" }
when = { field = "env:hour", op = "lt", value = 18 }
- Namespaces:
arg:(tool args — attacker-influenced),subject:(trusted tokenattrs),resource:(trusted tokenresource_attrs, tied to the rule’srequire_relation),env:(Warden environment). - Operators:
gt,lt,eq,contains. Numeric operators accept a number sent as a string.
Combinators:
when = { any = [ {arg="a",op="eq",value=1}, {arg="b",op="eq",value=2} ] } # OR
when = { not = { arg = "dry_run", op = "eq", value = true } } # NOT
when = [ {arg="a",op="gt",value=0}, {field="subject:role",op="eq",value="x"} ] # AND
Evaluation order
require_identity/ scope narrowing (authenticated agents may only call tools inscope).- Rules in order:
toolmatch →whenselects (non-match falls through) →require_role/require_relationgates →max_per_run→ the rule’sdecision. - Otherwise
default.
A when that doesn’t match falls through to the next rule — this is what lets
threshold pairs compose (amount < X → allow, else → require_approval).
Validate
warden policy lint --policy FILE # unreachable rules, unknown namespaces, zero budgets
warden policy test --policy FILE --tool NAME --args JSON [--token FILE]
See warden.policy.toml for a worked example and the per-provider policies under examples/.