EN

CLI reference

Under review — wording may still change.

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 edit opens the configuration in $EDITOR and 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-warden and /var/lib/purge-warden belong to the purge-warden user, and the daemon only talks to that user. The installed /usr/local/bin/warden is a small wrapper that runs the real binary as that user for you. Run as root or through sudo, it drops to purge-warden. Run as another user with sudo available, it uses sudo -u purge-warden. So warden status and sudo warden config backup both 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 init and warden config relocate. Call the real binary for them, with sudo.

  • 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 a config.toml.

  • Where the configuration is found. With no --config, Warden uses the first of these that it can open:

    1. ./config.toml
    2. $XDG_CONFIG_HOME/purge-warden/config.toml, or ~/.config/purge-warden/config.toml when $XDG_CONFIG_HOME is not set
    3. /etc/purge-warden/config.toml
    4. /var/lib/purge-warden/config.toml (the layout of hosts installed before 0.44.0)

    When root runs warden without --config, the first two are skipped, so a file planted in a shared directory cannot be picked up. The systemd units pass no --config either: they use the same search, effectively /etc and 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 edit does not; run warden reload or systemctl reload purge-warden after it.

  • Output. Most read commands print text or tables. --json exists on some of them (status, device list, stats …, and logs --format json), but not on any warden config command.

Exit codes

Every warden command uses the same exit codes, so a script can branch on them without reading the output.

CodeMeaning
0The operation succeeded.
1The operation failed: the daemon is not running, a write was refused, a download did not finish.
2The 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.
3The 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.
141The 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.

RetiredReplacement
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-denyThe same.
warden subnet profile-allow, warden subnet profile-denyThe same.
warden default allow, warden default denyThe same.
warden rule undoThe 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:

CommandPurpose
warden config showPrint the configuration.
warden config editEdit a copy in $EDITOR; apply it only if it is valid.
warden config lintValidate without changing anything.
warden config diffCompare the live configuration with another file.
warden config backupWrite a tar.gz snapshot.
warden config restoreReplace the live configuration from an archive.
warden config render-defaultPrint the built-in default configuration.
warden config relocateMove the configuration from /var/lib to /etc.

warden config show

text
warden config show [--resolved] [--annotate] [--section <name>]

Prints the configuration as merged TOML.

FlagEffect
--resolvedPrint what each device and subnet resolves to, as the five-level lookup would pick it.
--annotatePrint, 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

text
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:

bash
sudo warden config edit && sudo systemctl reload purge-warden
ExitMeaning
0The saved configuration is valid.
1The edit could not be made or written (editor, read, write or lock failure).
2The saved configuration is not valid, or a secondary refused it. The errors are printed.

warden config lint

text
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.

FlagEffect
--strictTreat warnings as failure: exit 2 on a valid configuration that carries warnings.
ExitMeaning
0The configuration is valid. Warnings, if any, were printed.
2The 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

text
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:

ExitMeaning
0The two configurations are identical.
3They differ. The differences are printed.
2One of them could not be loaded.

warden config backup

text
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

text
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.

ExitMeaning
0Restored, or the live configuration already matched.
1The 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

text
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:

bash
warden config render-default > /tmp/default.toml
warden config diff /tmp/default.toml

warden config relocate

text
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.

ExitMeaning
0Moved, rolled back, or the dry run found nothing to refuse.
1Refused, stopped part way, or the relabel failed.
2The configuration does not load.

The full runbook, with the refusals, is in Upgrade.

warden reload

text
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.

ExitMeaning
0The 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).
1It 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

↑↓ to navigate · Enter to open · Esc to close See all results