Skip to content

Rule Rhai

Rhai for rules — Rule Rhai — is Conduit’s scripted policy on matching rules: logic you cannot express with built-in actions alone. You keep .rhai files beside your config, reference them from rules via type: rhai, and Conduit runs them at Request rules and Response rules on the dataplane.

Rhai for rules acts on a policy txn object; it does not edit DNS wire bytes. For how rules and scripts fit together at the policy layer, see Policy & routing and Rules and actions.

When to use Rhai for rules

Built-in selectors and actions cover most routing — pool choice, tags, egress overrides, drop, and retry. Reach for Rhai for rules when you need logic on top of that, for example:

If declarative YAML is enough, prefer Rules and actions. Rhai for rules adds flexibility and operational surface (script files, sandbox limits, compile-time checks on reload), but runs an interpreted script on the query path for each matching rule — higher per-query cost than built-in actions alone. Prefer built-in selectors and actions when they express the same policy.

How scripts attach to rules

Rhai does not run on every query by default. A script runs only when a matching rule on that hook includes a rhai action whose value is the script path.

On each hook, Conduit still uses match_mode: first_match: it walks rules top to bottom and stops at the first rule whose selectors all match. On that rule, every action — built-in and type: rhai — runs in list order at the position where it appears.

The script receives a sandboxed txn object for the current transaction. It can refine what earlier actions already set — for example override pool choice or add tags — or drop / request retry on its own.

sequenceDiagram
  participant Hook as Request or response hook
  participant Rule as First matching rule
  participant Step as Next action in list

  Hook->>Rule: Selectors match?
  loop Each action in list
    Rule->>Step: built-in or rhai
    Step-->>Rule: txn effects
  end
  Rule-->>Hook: resolve drop / retry / continue

Hook timing, first-match rules, and YAML wiring: Rules and actions. Phase guards and pairing request/response scripts: Hooks and phases. Host API map: Host API overview. txn methods: Transaction API (txn).

Minimal example

Config — route names ending in .vip.example. through a script (paths resolve relative to the config file directory; see Config file — path resolution):

schema_version: 1
listeners:
  listeners:
    - address: "127.0.0.1:15353"
      protocol: udp
pools:
  - name: default
    backends:
      - address: "127.0.0.1:5300"
  - name: vip
    backends:
      - address: "127.0.0.1:5301"
rhai:
  max_operations: 10000
  max_call_depth: 32
  hook_timeout_ms: 50
rules:
  match_mode: first_match
  rules:
    - name: vip-routing
      hook: request
      selectors:
        - type: qname_suffix
          value: ".vip.example."
      actions:
        - type: rhai
          value: scripts/set-vip-pool.rhai

Script (scripts/set-vip-pool.rhai):

txn.set_tag("tier", "vip");
txn.set_pool("vip");

After SIGHUP, conduitctl reload, or conduitctl apply, Conduit compiles the script into the active runtime snapshot. Queries that match the rule run the script on the request hook before Route.

Configuration

Concern Where Topic page
Sandbox limits (operations, call depth, hook timeout) rhai: Sandbox limits
Script path on a rule rules: → type: rhai Rules and actions, Reference: rules
Lookup tables for scripts data_sources: Data sources, Lookups
Custom metric names and labels Declared in script source at compile time User metrics

When you omit the top-level rhai: block, Conduit still applies default sandbox limits (10000 operations, call depth 32, 50 ms hook timeout). You only need rhai: in the file when you want to tune those limits.

Omitting rules: entirely means no scripts run — Rhai is opt-in per rule.

When script changes take effect

Conduit reads and compiles .rhai files when it builds a runtime snapshot — at process start and on each successful reload or apply. Editing a script on disk has no effect on live queries until that snapshot swap succeeds.

  • conduitctl validate runs the same YAML checks and snapshot compile as startup/reload — use it to catch missing script paths or Rhai syntax errors before deploy.
  • Transactions already in flight keep the scripts they started with.
  • If reload validation fails (bad script syntax, missing file, invalid metric registration), Conduit keeps the previous working snapshot and DNS keeps flowing. See Configuration model.

Script errors and limits

Each hook invocation runs under sandbox limits (max_operations, max_call_depth, hook_timeout_ms). If a script traps, exceeds a limit, or calls an API not allowed on that hook (for example response() on the request hook), Conduit logs a warning and continues without applying further script effects for that hook — the query is not dropped solely because the script failed.

Built-in actions on the same rule still ran before the script. Use Logging at warn or higher to see rhai script error lines; built-in forward health and query counters still reflect the rest of the pipeline.

Read in order

  1. Host API overview — five scope objects
  2. Hooks and phases — request vs response from a script author’s view, phase guards, pairing scripts
  3. Transaction API (txn) — per-query policy methods and YAML equivalents
  4. Runtime API — runtime.routing() health reads
  5. Sandbox limits — rhai: fields, defaults, tuning and failure behavior
  6. Lookups — lookup() / lookup_ip() (Data sources for data_sources: config)
  7. User metrics — metrics.inc, conduit_user_* export

Prerequisites