relay binary is both the server and its operator commands. With no arguments it starts the server; a first argument naming one of the commands below runs that command instead.
Configuration
The server (relay with no command) first reads .env from the working directory, if present, and sets each variable that is not already set in the environment. The commands below do not read .env, so they never pick up a target or credentials from the directory they run in. To load a file for any invocation, name it in RELAY_ENV_FILE; the command then fails if the file can’t be read.
Control API commands (apply, export, auth can-i, token mint) call the control API over HTTP:
Database commands (
migrate, seed --apply, secret) connect to Postgres directly and need no running server. They read the same environment as the server, so an invalid RELAY_* value fails them as it would fail a boot. The variables they use:
apply, export, auth can-i, token mint, keygen and secret print errors to stderr as <command>: <message>. migrate and seed log as the server does, in JSON on stdout.
Running commands in a container
The lean image’s entrypoint is therelay binary, so a command is the container’s arguments:
docker exec -e RELAY_ADMIN_TOKEN=<token> <container> /relay export.
relay
Starts the inference listener (RELAY_PORT, default 8080) and the control listener (RELAY_CONTROL_PORT, default 8081), applying pending schema migrations first unless RELAY_MIGRATE_ON_BOOT=off. Every server setting is an environment variable; see Configuration.
On SIGTERM or SIGINT it stops accepting requests and waits up to RELAY_SHUTDOWN_DEADLINE_S seconds (default 15) for in-flight work. It exits 1 when the configuration is invalid, RELAY_PG_DSN is unset, Postgres can’t be opened, or a listener fails.
relay apply
.yaml and .yml file under a directory, sends the bundle to POST /api/apply, and prints the plan as a table with a count per action. See GitOps for the plan actions, dirty rows and pruning.
Before sending, it prints the control URL it targets and where that came from to stderr. When RELAY_ADMIN_TOKEN was set by the RELAY_ENV_FILE file rather than the environment or --token, it refuses to run without an explicit --url.
relay export
GET /api/export to stdout or a file. See Export for which rows are included.
Exits
0 on success, 2 when the server refused the request or could not be reached, and 1 on any other error.
relay auth can-i
POST /api/access-review and prints yes or no with the role binding or rule that decided it. <action> is <kind>.<verb> or a bare verb, which takes the resource’s kind. See Checking access.
Flags may appear before or after the positional arguments. Exits
0 when allowed, 1 when denied, and 2 when the arguments are invalid or the request fails. The server answers 501 under RELAY_AUTHZ=single.
relay token mint
POST /api/auth/login, mints an inference token with POST /api/auth/token, logs out, and prints the token to stdout. It needs an account with a password; the admin bearer names no user and cannot mint a token.
There is no password flag: command lines are visible in the process table and kept in shell history. The password comes from
$RELAY_PASSWORD, or from a prompt on an interactive terminal.
Exits 0 on success, 2 when the login or the mint is refused or the server can’t be reached, and 1 on a usage error or a missing password.
relay keygen
keyHash (sha256, hex) and its display prefix. Put the hash and prefix in a Key manifest and hand the plaintext to the caller; the plaintext never passes through the server. --prefix prints only the prefix of the generated key. Needs no configuration.
relay migrate
With no subcommand it prints a hint and exits
0. Every subcommand exits 1 on error. Stop the pods, or set RELAY_MIGRATE_ON_BOOT=off on them, before rolling back, or a restarting pod applies the migrations again. See Upgrading for the rollback procedure.
relay seed
--apply it only parses and validates the documents and logs a count per kind; it needs no database.
With --apply it applies pending migrations, then writes the documents straight to Postgres, without going through the control API: no authorization, governance or license checks apply, and every kind is accepted, including teams, projects, service accounts, keys, host keys, roles, bindings and users. Rows edited through the control API are skipped unless --dirty is given. Setting documents are skipped with a warning; settings are seeded from RELAY_SETTINGS_DIR at boot.
Exits
0 on success and 1 on any error.
relay secret
rotate, rewrap and destroy also work against a running fleet, which picks up the change within about a second. Every subcommand except status writes audit rows under the actor kind cli.
Exits
0 on success and 1 on any error, including a failed audit write after the change was made. See Stored secrets and key rotation for when to run each one.
Other tools
These are built from a checkout of the repository; the relay images don’t include them.relay-stats
Prints usage events and summaries from the control API as text tables, or JSON with--json.
--url (or set RELAY_CONTROL_URL) to the control listener with the /api prefix: the built-in default, http://127.0.0.1:8090, does not match the control listener’s default port. --token defaults to $RELAY_ADMIN_TOKEN.
Exits
1 when the request fails and 2 on a usage error. See Usage for the underlying API.
payload-migrate
Copies a JSONL dump from thefile payload-logging backend into the ClickHouse payload store, so captured bodies become readable through ClickHouse. Rows already present are skipped, so an interrupted run can be repeated.
See Payload logging for the backends.
catalog-server
catalog-server serve mirrors the catalog repository and serves its releases; catalog-server build builds one release’s files. It ships as its own image together with catalog-validate. See Catalog server.