Skip to content

Policy & routing

This section covers how Conduit decides where each client query goes upstream, what to change on the way out, and when to try again — declarative rules:, upstream pools: and backends, and retry limits on the dataplane.

Read Architecture and packet path first for pipeline phases and hook placement; YAML field lists are described on the topic pages below and in Reference.

How the pieces fit

Concern Config Topic page
Client IP allow/deny/tag by CIDR (ingress) acls: + type: cidr Client ACLs
Named CSV / CIDR tables for ACL and Rhai data_sources: Data sources
Match queries; set pool, tags, egress, or drop rules: Rules and actions
Scripted policy on matching rules rules: + type: rhai Rhai for rules (Rhai), Rhai policy
Group upstream resolvers and load-balance pools: Pools and backends
Exclude unhealthy backends from selection pools[].health Backend health
Caps and behavior on repeat attempts orchestrator: Retries and transactions, Reference: orchestrator
Default upstream timeout and egress address lists forward: Reference: forward, Dual-stack forwarding

On each transaction, policy currently runs at two hooks on the query path:

flowchart TD
  Parse[Parse] --> Req[Request rules]
  Req --> Route[Route — pool + backend]
  Route --> Fwd[Forward]
  Fwd --> Wait[Wait for response]
  Wait --> Res[Response rules]
  Res -->|continue / no retry| Send[Send]
  Res -->|retry| Route
  Req -->|drop| Drop[Drop]
  Res -->|drop| Drop
  1. Request rules run once after Parse. Selectors test the query; actions can set pool, tags, upstream egress source, or drop. No match → default pool path at Route.
  2. Route picks a backend in the selected pool (sticky weighted choice on the first attempt).
  3. After an upstream answer or forward timeout, Response rules continue to Send, drop, or request a retry (retry / retry_now) — looping back to Route, not re-running request rules.
  4. Send returns the final answer (or the transaction ends with drop or synthesized SERVFAIL when limits or pool exhaustion apply).

Rules and actions use match_mode: first_match: on each hook, Conduit walks the rule list top to bottom and stops at the first rule whose selectors all match. Actions on that rule — built-in and optional Rhai for rules — run in list order. See Rhai.

Read in order

  1. Client ACLs — optional ingress IP policy (acls:) before transaction slots
  2. Data sources — data_sources: CSV / CIDR tables shared by ACL and Rhai
  3. Rules and actions — rules: hooks, selectors, built-in actions, reload behavior
  4. Rhai for rules — scripted policy when built-in actions are not enough
  5. Pools and backends — pools: layout, weights, default pool, SERVFAIL when routing fails
  6. Backend health — active probes, passive fast-trip, eligibility, and freeze/drain controls
  7. Retries and transactions — response-hook retries, backend exclusion per attempt, orchestrator caps

Prerequisites

  • Minimal configuration — smallest runnable file (listeners, pools)
  • Config file — where rules:, pools:, orchestrator:, and forward: sit in the top-level map

Config reference

Block Reference
acls: Reference: acls
data_sources: / data_source_limits: Reference: data sources, Data sources
rules: Reference: rules
pools: Reference: pools
pools[].health Reference: health
orchestrator: Reference: orchestrator, Retries and transactions — Global limits
forward: Reference: forward, Dual-stack forwarding

Rule and pool changes load into the configuration runtime snapshot on reload or apply for new queries; in-flight transactions keep the policy they started with. See Configuration model and When changes to rules take effect.