Skip to main content
The YAML policy file gives you more advanced traffic control than inline rules or the plain-text rules file. To enable it, set 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 use remoteAddress.network(...)).
  • conditions — reusable named condition groups (optional).
  • rules — the ordered list of rules to evaluate (required).
Below is the example policy from examples/policy.yaml:

Defining networks

The networks 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 the rules 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.
When a rule has more than one condition, all conditions must be true for the rule to match (logical AND).

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 the User-Agent request 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 to true if 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 if str contains substr.
  • startsWith(str, prefix) — true if str starts with prefix.
  • matches(str, regex) — true if str matches the regular expression regex.
You can also call these as methods: 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 under conditions 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.