Import lists
Subscribe to a feed of domains — from the purge.cc catalog or from any URL you trust — then let each profile decide what to do with it.
What this step does
A list is a feed of domains. It carries no allow/deny nature of its own beyond a default: base on its [[blocklists]] row, which is deny unless you say otherwise. What actually happens to a list’s domains is decided per profile — profiles.<id>.lists maps a list id to deny, allow or ignore, and that override wins. With no override, the profile inherits base. One function answers the question for a (profile, list) pair: src/config/schema/blocklist.rs → effective_direction().
So a list is not an “allowlist” or a “blocklist”. It is a list, and the profile decides its nature. This page subscribes you to one, then points a profile at it.
Add a list
Browse the catalog
warden lists catalog
warden lists catalog --scope privacyThe four scopes are privacy, security, content and services. Rows already in your config are marked [active]:
purge.cc list catalog (5 lists, offline — using built-in data) privacy (5 lists): privacy/ads ads [active] privacy/devices devices privacy/general general privacy/mobile mobile privacy/tracking tracking [active] usage: warden lists add <list-id>
With network access the catalog is fetched live and each row carries a domain count. Because warden lists add resolves slugs offline, a list newer than your binary is marked [newer than this build] and printed with the URL to use instead.
Add one from the catalog
warden lists add privacy/adsadded: privacy/ads (list "privacy-ads") run `warden blocklist show privacy-ads` to check what it filters for
The id is the slug with its slash turned into a dash, so privacy/ads becomes privacy-ads — the same id warden init writes for the lists it subscribes you to, and the id you will type everywhere else.
Add any URL
warden lists add https://lists.example.org/ads.txtThe id is derived from the host and the file name — https://lists.example.org/ads.txt becomes lists-example-org-ads. Both halves are kept because either alone collides too easily. Any port and userinfo are dropped, anything outside a-z0-9- collapses to a dash, and the result is capped at 64 characters.
Two things can come back instead of a new subscription:
The URL is already subscribed. Not an error — re-running an install script should be quiet:
already subscribed: https://lists.example.org/ads.txt (list "lists-example-org-ads")
The derived id is taken by a different list. Two URLs on one host can genuinely reduce to one id, so this is refused rather than silently reported as success:
"https://lists.example.org/trackers/list.txt" would be named "lists-example-org-list", which is already taken by a different list (https://lists.example.org/ads/list.txt). Add it with a name of your own: warden blocklist add <name> --url https://lists.example.org/trackers/list.txt
Do what it says: run warden blocklist add and choose the id yourself.
What happens next
The list starts filtering, and there is no second step. Nothing was written into any profile — warden lists add does not attach the list to your default profile or to any other. It filters because base on the new row defaults to deny, and a profile with no override for that list inherits base.
One older channel behaves differently. If a subscription is recorded in the [lists].sources array — the form this verb used to write — it downloads on schedule and filters nothing, because no profile can reach it. warden lists add says so when it finds one, and warden lists list flags them under inactive entries in [lists].sources. Convert one by removing it and adding it again:
warden lists remove https://lists.example.org/ads.txt
warden lists add https://lists.example.org/ads.txtLet the profile decide
Override base for one profile, ask what is in force, or drop the override again:
warden profile list-policy show kids
warden profile list-policy set kids privacy-ads allow
warden profile list-policy clear kids privacy-adsThe same thing in the config file:
[profiles.kids]
lists = { privacy-ads = "allow" }clear and set … ignore are not the same move:
| You want | Use | What it means later |
|---|---|---|
| This profile never uses this list | set <profile> <list> ignore | A standing declaration. It survives a change to base. |
| This profile follows the list’s own default | clear <profile> <list> | The key is dropped. The pair follows base wherever it goes. |
set and clear both go over the daemon socket, never by direct file edit, and the daemon re-validates the whole config before the write lands. So a typo is refused before anything reaches disk — and a two-list change with one bad id writes neither.
A profile naming a list id that no [[blocklists]] row declares is an error, not a warning. Over the socket it is refused before the write; in a hand-edited file it fails at load:
profile "kids" names blocklist "privacy-ad" in its list policy, but no [[blocklists]] entry with that id is configured. Run `warden blocklist list` to see what is. profile "kids" sets lists.privacy-ad but no [[blocklists]] entry has id "privacy-ad" suggestion: add a [[blocklists]] entry with that id, or remove the entry from this profile's `lists`
Pointing a profile at a list with allow means that feed can unblock domains on your network. If the list is not trust = "local", Warden refuses the allow until you say you accept that — --accept-unsigned-allow on the command, or accept_unsigned_allow = true on the [[blocklists]] row. Whoever publishes that feed can add a domain to it tomorrow and it will be permitted here.
deny and ignore are not gated: both narrow what a profile permits, so there is nothing to declare.
Import a local file
For a list you wrote yourself, or one you downloaded and want to keep frozen:
warden blocklist import-local ./office-deny.txt --id office-deny --kind denyImported './office-deny.txt' as blocklist 'office-deny' (kind=deny, 412 entries).
The file is copied into the directory Warden manages for lists — lists/<id>.txt beside your config, so /var/lib/purge-warden/lists/office-deny.txt on a default install — and registered with trust = "local". The format is detected from the content. --kind accepts deny, allow or ignore here. Because the result is local, an allow import needs no acknowledgement.
Editing the copy afterwards means editing the copy, not your original.
warden lists or warden blocklist?
Both families write the same object. warden lists add calls the same writer warden blocklist add does, so a list added either way is one [[blocklists]] row with the same validation and the same audit record.
warden lists … | warden blocklist … | |
|---|---|---|
| What it is | The subscription front door | Direct CRUD on [[blocklists]] rows |
| You name a list by | Catalog slug or URL | Its id |
| The id is | Derived for you | Yours to choose |
| Also covers | The catalog, refresh, the download cache | set-kind, set-trust, import-local |
| Reachability probe on add | Skipped, so a server that is down today does not block the subscription | Runs, unless --skip-head-check |
Note that the flag is spelled --kind while the field it writes is base. They are the same thing: the list’s own default direction.
CLI reference
| Verb | What it does |
|---|---|
warden lists catalog [--scope <s>] | Browse the purge.cc catalog, optionally one scope |
warden lists add <slug|url> | Subscribe. Derives the id, writes the [[blocklists]] row |
warden lists list | Every configured source, plus any inactive legacy entry |
warden lists refresh | Re-download every list now and rebuild the filter |
warden lists remove <slug|url|id> | Unsubscribe, whichever channel the entry lives in |
warden lists forget <slug|url> | Drop the cached body and headers; config untouched |
warden blocklist show <id> | One list in full, including which profiles enforce it |
warden blocklist add <id> --url <u> | Register a subscription with an id and flags you choose |
warden blocklist import-local <path> --id <id> --kind <deny|allow|ignore> | Copy a local file in and register it as trust = "local" |
warden blocklist set-kind <id> <deny|allow> | Change the list’s base |
warden profile list-policy set <profile> <list> <deny|allow|ignore> | Override base for one profile |
warden profile list-policy clear <profile> <list> | Drop the override; follow base again |
warden profile list-policy show <profile> | What is in force for every list, and where it came from |
In the TUI
Launch with warden dashboard, press 4 for the Filters section, then g i for the Lists leaf.
The leaf answers the same question warden blocklist show <id> does: for each list, the direction actually in force per profile, asked of effective_direction() rather than recomputed. If a list reaches nobody, both surfaces say so.
See also
- Profiles — the canonical page for the entity that decides a list’s direction.
- Create profiles — the next step: build the profiles whose policy you just set.
- Custom rules — for domains you write yourself, one at a time, instead of subscribing to a feed.
- Initialize — the three lists a fresh install already subscribes to.