CLI reference
The warden command: global rules, exit codes, and the warden config verbs.
What this is
A reference for warden, the one binary that ships with purge-warden. This
page covers the rules that apply to every command, the exit codes a script can
rely on, and the warden config verbs that work on the configuration as a
whole. Commands that manage one kind of thing (warden device …,
warden blocklist …, warden profile …, warden custom-list …) are
documented on their own configure pages. Run warden --help or
warden <command> --help for the full list on your machine.
Warden does not have a generic config get <key> or config set <key> <value>. You change the configuration in these ways:
warden config editopens the configuration in$EDITORand checks it when you save.- The per-thing commands (
warden device add,warden blocklist set,warden profile …,warden subnet add,warden local-dns add,warden device quiet,warden custom-list …and so on). Each one reloads the running daemon for you. warden config restore <archive>puts back a known-good configuration in one operation.
Conventions
Which user. The files in
/etc/purge-wardenand/var/lib/purge-wardenbelong to thepurge-wardenuser, and the daemon only talks to that user. The installed/usr/local/bin/wardenis a small wrapper that runs the real binary as that user for you. Run as root or throughsudo, it drops topurge-warden. Run as another user withsudoavailable, it usessudo -u purge-warden. Sowarden statusandsudo warden config backupboth work as written.The real binary. The binary is
/usr/local/libexec/purge-warden/warden. A few commands need to run as root and refuse the wrapper’s user:warden initandwarden config relocate. Call the real binary for them, withsudo.Passing
--config. An explicit--config <path>skips the wrapper’s routing. The command then runs as whoever you are. It goes before the subcommand:warden --config /path/config.toml config lint. The wrapper also runs the binary as you, without switching user, when the current directory holds aconfig.toml.Where the configuration is found. With no
--config, Warden uses the first of these that it can open:./config.toml$XDG_CONFIG_HOME/purge-warden/config.toml, or~/.config/purge-warden/config.tomlwhen$XDG_CONFIG_HOMEis not set/etc/purge-warden/config.toml/var/lib/purge-warden/config.toml(the layout of hosts installed before 0.44.0)
When root runs
wardenwithout--config, the first two are skipped, so a file planted in a shared directory cannot be picked up. The systemd units pass no--configeither: they use the same search, effectively/etcand then/var/lib.Safe writes. Every write goes through a temporary file in the same directory, a check, then a rename. If the check fails, the live file is unchanged.
Reloading. The per-thing commands reload the daemon on their own.
warden config editdoes not; runwarden reloadorsystemctl reload purge-wardenafter it.Output. Most read commands print text or tables.
--jsonexists on some of them (status,device list,stats …, andlogs --format json), but not on anywarden configcommand.
Exit codes
Every warden command uses the same exit codes, so a script can branch on them
without reading the output.
| Code | Meaning |
|---|---|
0 | The operation succeeded. |
1 | The operation failed: the daemon is not running, a write was refused, a download did not finish. |
2 | The configuration could not be loaded, or is not valid. Also what the command-line parser uses for a usage error (an unknown flag or a missing argument). A usage error always prints a Usage: block. |
3 | The answer is “no”. Only for read-only checks: warden query found the domain blocked, warden resolve found the source REFUSED, warden config diff found a difference. |
141 | The output was closed early, for example warden … | head. |
The custom-list and profile mount commands use 3 for a conflict (for example a revision mismatch or a list that is still mounted) and add their own codes 4 (failed
before the commit, or the reply was lost) and 5 (committed but not active yet).
See their pages.
Retired verbs
Some verbs from older releases still appear in --help. They are retired in 0.44.0. They accept their old arguments, write nothing, and point you to the replacement. Do not use them in scripts.
| Retired | Replacement |
|---|---|
warden profile allow, warden profile deny, warden profile admin-rule … | A Custom List mounted on the profile. |
warden device allow, warden device deny, warden device rules … | The same. |
warden group profile-allow, warden group profile-deny | The same. |
warden subnet profile-allow, warden subnet profile-deny | The same. |
warden default allow, warden default deny | The same. |
warden rule undo | The same. |
warden tags … | Nothing. Tags no longer decide which lists apply; use warden profile list-policy. |
Use warden custom-list to write the rules and warden profile mount to attach the list. See Custom rules.
warden config
The configuration commands live under warden config. There are eight:
| Command | Purpose |
|---|---|
warden config show | Print the configuration. |
warden config edit | Edit a copy in $EDITOR; apply it only if it is valid. |
warden config lint | Validate without changing anything. |
warden config diff | Compare the live configuration with another file. |
warden config backup | Write a tar.gz snapshot. |
warden config restore | Replace the live configuration from an archive. |
warden config render-default | Print the built-in default configuration. |
warden config relocate | Move the configuration from /var/lib to /etc. |
warden config show
warden config show [--resolved] [--annotate] [--section <name>]
Prints the configuration as merged TOML.
| Flag | Effect |
|---|---|
--resolved | Print what each device and subnet resolves to, as the five-level lookup would pick it. |
--annotate | Print, before the configuration, a commented block that gives the file and line each entity came from. |
--section <name> | Print only one top-level section, for example server, upstream, devices, profiles, subnets or cache. With --resolved, only devices, subnets and server can be shown. |
Without --resolved, the output is TOML. With --resolved, it is a text
report. For machine use, pipe the plain TOML through a TOML tool such as
tomlq or yq -p toml.
warden config edit
warden config edit
Opens a private copy of the configuration in $EDITOR (vi if it is not set). The
live file is never open in the editor. When you save and quit, Warden checks the
copy. The live configuration changes only if the copy is valid.
If the copy is refused, or the editor exits with an error, the live configuration stays as it was, the copy is kept, and the command prints its path. On a cluster secondary, a change to the policy that comes from the primary is refused; make that change on the primary.
This command does not reload the daemon. Chain it with a reload:
sudo warden config edit && sudo systemctl reload purge-warden| Exit | Meaning |
|---|---|
0 | The saved configuration is valid. |
1 | The edit could not be made or written (editor, read, write or lock failure). |
2 | The saved configuration is not valid, or a secondary refused it. The errors are printed. |
warden config lint
warden config lint [--strict]
Loads and checks the configuration without touching the running daemon. Warnings are printed to stderr. By default they do not fail the command, because a warning means the daemon still starts and serves.
| Flag | Effect |
|---|---|
--strict | Treat warnings as failure: exit 2 on a valid configuration that carries warnings. |
| Exit | Meaning |
|---|---|
0 | The configuration is valid. Warnings, if any, were printed. |
2 | The configuration has errors or could not be loaded. Each error is printed with its file and line. |
Safe to gate a deploy on: warden config lint && systemctl reload purge-warden.
warden config diff
warden config diff <other>
Compares the live configuration with <other>, a path to another
configuration file. “They differ” is a successful answer, so it has its own
exit code:
| Exit | Meaning |
|---|---|
0 | The two configurations are identical. |
3 | They differ. The differences are printed. |
2 | One of them could not be loaded. |
warden config backup
warden config backup [--out <dir> | --auto | --reset-auto-failure]
Writes config-<UTC-timestamp>.tar.gz to [backup] dir, or to a backups/
directory next to the master when that is not set. With --out <dir>, it
writes there instead. When the configuration does not load, the directory
follows the rule in Where archives go.
--auto and --reset-auto-failure are for the scheduled backup. The three
flags exclude one another.
Exit 0 on success, an automatic run that was not due, or an --auto run that
skipped a configuration that does not load. Exit 75 if another backup is
running.
For what is in an archive, the schedule and limits, see Backup & restore.
warden config restore
warden config restore <archive> warden config restore --list warden config restore --latest
Checks the archive, then replaces the live configuration in one transaction and asks the daemon to reload. It never changes the node’s cluster membership. It refuses an archive from Warden 0.41 or earlier.
| Exit | Meaning |
|---|---|
0 | Restored, or the live configuration already matched. |
1 | The archive failed validation (the live configuration is unchanged), or the restore could not be completed. |
Restore keeps no copy of the current configuration: if you may want it back,
run warden config backup first. See
Backup & restore for the steps and the
refusals.
warden config render-default
warden config render-default
Prints the built-in default configuration to stdout. It needs no root, writes no file, and ignores which configuration Warden would otherwise use. Useful for comparing your configuration with the shipped default:
warden config render-default > /tmp/default.toml
warden config diff /tmp/default.tomlwarden config relocate
sudo /usr/local/libexec/purge-warden/warden config relocate [--dry-run] [--reverse]
Moves the configuration set from /var/lib/purge-warden to
/etc/purge-warden. It runs offline, as root, with the real binary, and it
refuses --config. --dry-run runs every check and moves nothing. --reverse
moves the set back, or rolls back an incomplete forward run.
| Exit | Meaning |
|---|---|
0 | Moved, rolled back, or the dry run found nothing to refuse. |
1 | Refused, stopped part way, or the relabel failed. |
2 | The configuration does not load. |
The full runbook, with the refusals, is in Upgrade.
warden reload
warden reload
Asks the running daemon, over its authenticated control socket, to reload its
configuration and lists. Use it after warden config edit. Here the reload is
the whole operation, so a daemon that is not running is a failure.
| Exit | Meaning |
|---|---|
0 | The daemon accepted the reload request. The reload itself runs afterwards: if the daemon then rejects it, for example because a changed field needs a restart, the command still exits 0, prints daemon reloaded — config and lists are live, and the reason is only in journalctl -u purge-warden and the audit log (warden audit tail). |
1 | It did not: the daemon is not running, there is no token, or the reload was refused. |
warden migrate
warden migrate v4-to-v5 is the schema 4 to schema 5 migration. The upgrade
runs it for you inside its transaction. The manual form exists only as a
recovery tool; see Upgrade.
See also
- Backup & restore: the operational guide for
config backupandconfig restore. - Upgrade:
install.sh --upgradeandwarden config relocate. - Basic configuration: where the configuration lives, and how to validate and reload it.
- File paths: where Warden reads and writes on disk.
- Environment variables:
$EDITOR,$XDG_CONFIG_HOMEand the installer settings.