policy_file in config.json to the path of your YAML file. When policy_file is set, it takes priority over rules_file and any inline rules defined in config.json which also allows for hot reload (where you do not have to restart verifyngo for changes to take effect), unlike the other files, which don’t have that capability.
Structure of a policy file
A policy file has up to three top-level keys:networks— named groups of IP ranges (required if your rules useremoteAddress.network(...)).conditions— reusable named condition groups (optional).rules— the ordered list of rules to evaluate (required).
examples/policy.yaml:
Defining networks
Thenetworks section maps a name to one or more source entries. verifyngo resolves all entries at startup and builds a fast lookup table for checking IPs at request time. You can mix source types within the same group.
For
url and file sources you can add a jq-path key to extract CIDRs from a JSON response, or a regex key with a named capture group called prefix to extract CIDRs from arbitrary text.
Writing rules
Each rule in therules list has a name, one or more conditions, and an action. Rules are evaluated top to bottom; the first matching rule wins. If no rule matches, default_action from config.json applies.
Available actions are allow / pass (let the request through), challenge / check (serve a CAPTCHA), and deny / drop (block immediately). The paired words are aliases for the same behaviour.
Condition variables
These variables are available in every condition expression:path— the request URL path string (e.g."/blog/post-1").userAgent— the value of theUser-Agentrequest header.method— the HTTP method (GET,POST, etc.).ip— the client IP address as a string.headers["Header-Name"]— the value of any request header, accessed by its exact name.remoteAddress.network("name")— evaluates totrueif the client IP is a member of the named network group.
Condition functions
Three helper functions are available for string matching:contains(str, substr)— true ifstrcontainssubstr.startsWith(str, prefix)— true ifstrstarts withprefix.matches(str, regex)— true ifstrmatches the regular expressionregex.
userAgent.contains("bot"), path.startsWith("/api"), path.matches("^/post/[0-9]+").
Named condition groups
If the same set of conditions appears in multiple rules, define it once underconditions and reference it in rules using ($name). When a rule contains a ($name) reference, verifyngo expands the group inline and OR-joins the individual expressions within it before applying the rule’s AND logic.
Hot-reload applies to the policy file too. verifyngo watches the file and picks up any changes within about 10 seconds — no restart required.