Filtering process
Warden’s configuration has seven nouns: blocklists, admin rules, profiles, devices, groups, subnets, schedules. Once you see how they reference each other and in what order the resolver consults them, the rest of the documentation reads as variations on a single theme. This page is that theme.
How a query gets resolved
For each query, Warden runs a single cascade in two phases: first picks the profile (first ladder), then asks that profile what to do with the domain (second ladder).
The first phase — which profile applies? — walks five levels in a fixed order. The first level that matches wins. The second phase — what does that profile say about this domain? — walks the rule layers inside the chosen profile.
Phase 1 — which profile applies? · first match wins
- L2
Schedule active for this device?
[[schedules]]yes → profile - L1
Client IP/MAC has a device row?
[[devices]]yes → profile - L3
Device belongs to a matching group?
[[groups]]yes → profile - L4
Client IP inside a subnet CIDR?
[[subnets]]yes → profile - L5
default_profileset?[server]yes → profile - REFUSEDhardcoded — ignores any
block_response
Phase 2 — what does that profile say about the domain?
- R1
Device
allow_ruleshit? yes → Allow - R2
Device
deny_ruleshit? yes → Block - R3 Profile admin-rule allow hit? yes → Allow
- R4 Profile admin-rule deny hit? yes → Block
- R5
Domain in any subscribed blocklist?
[[blocklists]]yes → Block - Allowno layer objected
A few things these ladders pin down that prose alone tends to slide over.
Schedule wins over the device’s direct profile, not the other way around. The numbering above isn’t accidental: schedule is L2 and the direct device row is L1, but the resolver checks L2 first. The reasoning is operator intuition — if you write a schedule for a device that already has a direct profile, you clearly want the schedule to win during its window, otherwise the schedule would have no effect at all.
Schedules only fire if the client matched a device row. A schedule is keyed to a device id (or a group id, indirectly via device.groups). A client resolved at L4 (subnet) or L5 (default) can’t trigger a schedule even if the schedule’s overlay profile is the same one they end up on. If you need time-bounded behaviour for a “device-less” client, model it with separate subnets or with future per-rule schedules — not with [[schedules]].
Groups don’t accept raw IPs. A [[groups]] row references device ids only. A client without a device row can never reach L3, period. This is why “lock down the kids’ VLAN at 8pm” is usually expressed as kids-VLAN subnet → kids-strict profile, not as a group with a schedule.
Longest prefix, not first declared. When two [[subnets]] overlap, the more specific CIDR wins regardless of file order. The optional priority field on subnets is informational; the engine uses longest-prefix.
override_profile_deny gates a narrow cell. A device-level allow rule can freely allow domains that the profile would block via blocklists — no override needed. The override flag is required only when the device.allow conflicts with a profile-level admin rule deny on the same domain. The validator refuses that combination at write time unless override_profile_deny = true.
Strict-by-default fallback
If no level matches and default_profile is unset, the answer is REFUSED — never a permissive default.
Pre-SN3 there was a dedicated server.block_unmapped_clients flag that made this explicit. SN3 retired the flag because the same effect falls out of the cascade: leave default_profile unset and any client that doesn’t match a device, group, or subnet drops to L5 and gets refused. The RCODE=REFUSED at L5 is hardcoded — it ignores any profile’s block_response, so a permissive profile can’t accidentally become the network’s open-resolver mode.
Set default_profile only when you actually want a catch-all policy (e.g. every guest gets the “ads-blocked” profile). Leaving it unset is the strict-allowlist posture.
The cast
Profiles are the centre. Everything else either points at a profile or is referenced by one.
A profile is a bundle of policy: which blocklists to subscribe to, which admin rules to attach, what to answer with when a query is blocked. Devices, groups, and subnets are three different ways of saying “this client gets that profile”. Schedules are a time-bounded override that swaps in a different profile during a window. Blocklists and admin rules are the raw policy that profiles compose.
| Entity | Identified by | Points to | Referenced by |
|---|---|---|---|
[profiles.id] | id | blocklists, admin_rules | devices, groups, subnets, schedules, server.default_profile |
[[devices]] | ip and/or mac | profile, groups, allow_rules, deny_rules | groups (via id), schedules |
[[groups]] | id, priority | profile, devices | devices (via device.groups), schedules |
[[subnets]] | id, cidrs | profile | — |
[[schedules]] | target_type + target_id | a device or a group, profile | — |
[[blocklists]] | id | external feed URL | profiles |
[[admin_rules]] | id | one rule (allow/deny/regex) | profiles, devices |
A few cardinality facts the table doesn’t shout:
- A device points at one profile (optional). It can belong to many groups.
- A group has one profile and many devices.
- A subnet has one profile and many CIDRs.
- A blocklist or an admin rule is referenced by many profiles.
- A schedule has exactly one target (a device or a group, never both) and one overlay profile.
The split between identity (devices, groups, subnets) and policy (profiles, blocklists, admin_rules) is deliberate. Identity entities never carry inline rules — they only point at a profile. That’s why the same profile can govern your laptop, the kids’ tablets, and the guest VLAN without three duplicate copies of the same ruleset.
Where each entity is documented
This page is the map. The territory lives one click away.
- Profiles — the policy bundle every other entity points at: see Profiles.
- Devices, Groups, Subnets — the three identity layers that feed L1 / L3 / L4: see Devices, Groups, Subnets.
- Admin rules — the typed allow/deny/regex rules referenced by profiles and (per-id) by devices: see Admin rules.
- Schedules — time-bounded profile overlays for matched devices and groups: see Schedules.
- Blocklists — external domain feeds subscribed by profiles: see Blocklists.
- The full TOML schema — every field, every default, every constraint: see the Warden TOML schema.