CLI
Run rivet --help or rivet COMMAND --help for built-in help. Commands are listed in workflow order: preparing and compiling configuration, working with hosts, then releases and agents.
Global options
--plugin-lock FILE works with every command. It selects the approved plugin installations; without it, Rivet reads /etc/rivet/plugins.lock.json if it exists. The lock pins each plugin’s executable path, checksum, release, and descriptor. It never downloads anything.
plugin-inspect runs the named binary and prints a proposed lock entry. Review it before installing. Plugin binaries and locks must be in protected locations, and root runs require root-owned files. Invalid locks, checksum mismatches, unsupported protocols, and conflicting registrations fail before any plugin runs. Over SSH, the host uses its own lock; the controller’s --plugin-lock doesn’t apply there.
init
Downloads and verifies remote module sources, including those of nested modules, into .rivet/modules, and writes rivet.lock.json. Commit the lockfile and ignore the cache. Needs Git for Git sources and curl for HTTPS archives. validate and compile never fetch modules; they require init to have run.
validate
Checks configuration without writing a bundle. Without --facts, it uses the built-in Ubuntu baseline. Cloud file sources are downloaded to check their checksums, and SOPS layers are decrypted.
--vars-file FILEsupplies variable values from one YAML or JSON file (.jsonselects JSON; anything else is YAML).--data-hierarchy FILEselects a data hierarchy manifest. Values from--vars-filereplace hierarchy values.--explain-inputsshows where each input value came from, without printing values. Sensitive variables are shown by name only.--explain-skipped-layersalso lists optional hierarchy layers that were missing. It requires--explain-inputs.
compile
Evaluates configuration against facts and writes a bundle with mode 0600. --facts takes a snapshot from rivet facts or a target assumptions file. --out must not exist; Rivet never overwrites a bundle. Input flags work as for validate. Functions, file reads, templates, SOPS decryption, and cloud downloads all happen here.
test
Runs the tests/*.rivettest.hcl suites in DIRECTORY (default .) against compiled catalogs, without touching any host. --recursive includes suites in child directories. --filter selects cases whose suite > test [variant] name contains TEXT. An empty run fails unless --allow-empty is set. See testing configurations.
graph
Verifies the bundle and prints resources in execution order, followed by each ordering edge and its reason. Values, outputs, and file contents are never printed. JSON output for configurations with modules also includes module boundary nodes and edges.
Host commands
facts, plan, apply, and journal run on a host. Choose it with exactly one of:
--local: this machine, which must be Linux.--target DESTINATION: a remote host over SSH, such asuser@example.orgor aHostalias. Works from macOS.
These flags require --target. --timeout-seconds N limits the runner session (1 to 86400 seconds, default 86400) and also works with --local. Over SSH, --facts-dir and --state-dir are paths on the remote host. See SSH from a controller.
Applying changes requires root on the host. With SSH, log in as root or add --sudo.
facts
Prints a JSON snapshot of the host: platform, hashed identity, capabilities, built-in inventory, and custom facts from DIR (default /etc/rivet/facts.d). Executable custom facts run as the runner’s user. See facts.
plan
Predicts changes without writing anything to managed objects or runner state. Over SSH, it may still upload a runner; add --installed-only to prevent that. See plan and apply.
apply
Converges the host. --noop behaves like plan. --state-dir uses a different private journal directory (default /var/lib/rivet); the host lock is always /run/rivet/apply.lock. Work left pending by an interrupted earlier run is always recovered first. See recovery.
journal
Prints unresolved intents and refreshes as JSON, opening the journal read-only. Root’s journal is in /var/lib/rivet; an unprivileged user’s default is in their XDG state directory. To read root’s journal, run as root, use --sudo, or pass a --state-dir you can read.
Releases
release publishuploads an immutable snapshot and prints itssha256:digest. It doesn’t change any environment.release validatecompiles the environment’s release without downloading asset contents. Without--facts, it uses the built-in Ubuntu baseline.release compilealso downloads and verifies every asset, and writes a standalone bundle.environment promotepoints an environment at a release after checking the release is complete.--expected-generation 0requires a new environment; a positive value requires that current generation. Concurrent promotions are detected either way.environment showprints the environment’s current release and generation as JSON.
The environment defaults to production. Digests can be given with or without the sha256: prefix. See releases and environments.
run
The agent: gets a catalog, verifies its assets, then applies it locally. Applying requires Linux and root. --prepare-only writes the bundle instead and works on macOS.
--source and --server can’t be combined. Releases don’t support --vars-file or data hierarchies.
rivet-server
The separate compile service binary. It needs a source store, TLS certificate and key, one authentication method (GCP, mTLS, or OIDC), and at least one allow rule. See compile service.
Exit codes
A failure always takes precedence over 3. In automation, treat 3 as success with changes. rivet test returns 0 when all cases pass, 1 for failed cases, and 2 for invalid definitions, setup errors, or an empty run.