specverb policy: auth, deny, restrict, tiering
The policy surface a Guardfile authors over the op-bound grants. Engine and layering in specverb.md.
Auth
A secret or opaque host is named, never committed: value <provider> "<address>". umbra never reads the store. A registered provider does, and an unregistered one fails closed. See value providers.
Three schemes, each redacting its secrets in --dry-run: header-token { header; prefix; value ... } (the trailing space in prefix "token " is significant), bearer, and query-param.
auth none states that the upstream takes no credential: authorize returns without touching the request. The block stays required, because a spec omitting auth is a spec that forgot, and auth none carrying a block is an error. A placeholder is not a substitute: value literal "unused" sends a wrong Authorization rather than none, and an endpoint serving anonymous callers can still reject a credential it cannot verify.
base-url takes a committed string or a block resolving the host through a provider at request time, lazily and cached, so mounting the tree never touches the store. The forms are mutually exclusive. With no committed host the spec is vendored beside the guardfile.
Deny beats allow - restrict gates scope
cannot/never <verb> <resource> blocks that class and beats any matching can. The allowed leaf is dropped from the tree, the spec lock, and the action poll set, replaced by a teaching leaf failing closed with PolicyDenied and the grant's message. A deny with no allow still mounts that leaf, so an operator learns why rather than hitting an unknown command.
restrict <param> matches "<glob>"... is a wrap-level allowlist. Every leaf whose path carries {param} must supply a matching argument at invocation or fail closed before any wire call. A malformed glob matches nothing, and it is enforced on the action path too.
inherit and override
inherit "<path>" pulls in another guardfile's grants, so a tiered surface composes by layering. Resolution is textual, before the typed parse: each file is flattened recursively and its wrap body spliced in. Effective grants are the union, order-independent. restrict inherits deduped by param with the child winning, singletons only when the child declares none, and action blocks stay child-local. A missing ref or cycle fails closed.
The load-bearing rule: an inherited never beats a plain can, and only an override naming the exact verb+resource beats an inherited never. Deny low, override high.
override can <verb> <resource> re-grants exactly that pair and rejects "*", so every escalation is enumerated. Enforced when guardfiles flatten, not at runtime: a plain can shadowed by an inherited never is a build error pointing at override, and an override lifting no matching never is one too, since silently it would be a plain can.