CLI Reference
Brokkr provides three command-line binaries: brokkr-broker for the central management server, brokkr-agent for the cluster-side agent, and brokkr, the control-plane client (documented in the brokkr section below). The two server binaries are configured through embedded defaults, an optional BROKKR_CONFIG_FILE TOML layer, and environment variables; brokkr uses its own flags / ~/.brokkr/config (see its section).
brokkr-broker
Section titled “brokkr-broker”The broker binary runs the central API server and provides administrative commands for managing agents, generators, and keys.
Commands
Section titled “Commands”brokkr-broker serve
Section titled “brokkr-broker serve”Starts the broker HTTP server on 0.0.0.0:3000.
brokkr-broker serveEndpoints exposed:
| Path | Purpose |
|---|---|
/api/v1/* |
REST API (see API Reference) |
/healthz |
Liveness probe |
/readyz |
Readiness probe |
/metrics |
Prometheus metrics |
/swagger-ui |
Interactive API documentation |
/docs/openapi.json |
OpenAPI 3 specification |
/ |
Operator Console — the read-only web view of fleet, deployments, and telemetry. Any path not owned by /api or /internal falls back to the console shell |
The console is served only by builds that include the embed-ui feature. The published broker container image is built that way, so a stock brokkr-broker container serves the console on the same port as the API; a binary you build yourself without the feature serves a placeholder instead.
brokkr-broker create agent
Section titled “brokkr-broker create agent”Creates a new agent record, generates its initial PAK, and registers it with the system generator plus any generators you name.
brokkr-broker create agent --name <name> --cluster-name <cluster> [--generator-ids <uuid,...>]Flags:
| Flag | Required | Description |
|---|---|---|
--name |
Yes | Human-readable agent name |
--cluster-name |
Yes | Name of the Kubernetes cluster this agent represents |
--generator-ids |
No | Additional generators to register the agent with. Accepts a comma-separated list, and may be repeated. |
Every agent is registered with the system generator (the fleet scope) whether or not you pass --generator-ids, which matches what POST /api/v1/agents does. Each ID you pass is checked before anything is created, so a typo fails the whole command rather than leaving a half-registered agent behind.
Output:
Agent created successfully:ID: a1b2c3d4-e5f6-7890-abcd-ef1234567890Name: production-us-eastCluster: us-east-1-prodInitial PAK: brokkr_BRx9y2Kq_A1B2C3D4E5F6G7H8I9J0K1L2Registered with: system (fleet scope), f8e7d6c5-b4a3-2109-8765-432109876543Important: The PAK is only displayed once. Store it securely.
If the broker has never been started against this database, the system generator does not exist yet. The agent is still created, but the command logs a warning and the Registered with: line omits the fleet scope — start the broker once to provision the system generator, then register the agent with brokkr register.
brokkr-broker create generator
Section titled “brokkr-broker create generator”Creates a new generator for CI/CD integration.
brokkr-broker create generator --name <name> [--description <desc>]Flags:
| Flag | Required | Description |
|---|---|---|
--name |
Yes | Generator name (1-255 characters) |
--description |
No | Optional description |
Output:
Generator created successfully:ID: f8e7d6c5-b4a3-2109-8765-432109876543Name: github-actionsInitial PAK: brokkr_BRy8z3Lp_M1N2O3P4Q5R6S7T8U9V0W1X2brokkr-broker rotate admin
Section titled “brokkr-broker rotate admin”Re-runs the admin-key upsert.
brokkr-broker rotate adminBehavior depends on broker.pak_hash, and the command reports which branch it took:
- If
broker.pak_hashis set and non-empty, the configured hash is validated and stored. An unset value takes this branch too, because the embedded default configuration supplies the publicly known development hash. In this branch no new PAK is generated and nothing is revoked. Any PAK matching that hash keeps working. The output says so and lists the two ways to actually replace the credential. - If
broker.pak_hashis an explicit empty string (for exampleBROKKR__BROKER__PAK_HASH=""), a new admin PAK is generated and its hash stored. Both the PAK and its hash are printed; the PAK is shown once and cannot be recovered from the hash. It is also written to/tmp/brokkr-keys/key.txt, which is deleted on graceful shutdown.
The old admin PAK stops working only on the second branch, where the stored hash actually changes. Take the printed hash as well as the PAK — it belongs in BROKKR__BROKER__PAK_HASH (or the chart’s broker.pakHash / broker.pakHashExistingSecret), and it cannot be derived from the PAK with sha256sum because only the long-token component is hashed.
See Managing PAKs for the full flow, including the Kubernetes cold start.
brokkr-broker rotate agent
Section titled “brokkr-broker rotate agent”Rotates an agent’s PAK.
brokkr-broker rotate agent --uuid <uuid>Flags:
| Flag | Required | Description |
|---|---|---|
--uuid |
Yes | The agent’s UUID |
Prints the new PAK to stdout (shown once). The REST endpoint POST /api/v1/agents/{id}/rotate-pak is equivalent and additionally invalidates the broker’s auth cache immediately; after CLI rotation the old PAK may continue to authenticate for up to broker.auth_cache_ttl_seconds (default 60).
brokkr-broker rotate generator
Section titled “brokkr-broker rotate generator”Rotates a generator’s PAK.
brokkr-broker rotate generator --uuid <uuid>Flags:
| Flag | Required | Description |
|---|---|---|
--uuid |
Yes | The generator’s UUID |
Prints the new PAK to stdout (shown once). The REST endpoint POST /api/v1/generators/{id}/rotate-pak is equivalent and additionally invalidates the broker’s auth cache immediately; after CLI rotation the old PAK may continue to authenticate for up to broker.auth_cache_ttl_seconds (default 60).
brokkr-broker generate-pak
Section titled “brokkr-broker generate-pak”Mints an admin PAK and its SHA-256 hash offline, for day-zero bootstrap. Contacts neither the database nor a keyfile.
brokkr-broker generate-pakPrints the PAK (the admin credential — store securely) and its hash. Set the hash as BROKKR__BROKER__PAK_HASH before the broker’s first startup; the broker stores it on the admin role at boot.
Output:
Minted admin PAK (offline — nothing was written to the database):
PAK (secret — send as `Authorization: Bearer <PAK>`; store securely): brokkr_BRx9y2Kq_A1B2C3D4E5F6G7H8I9J0K1L2
PAK hash (set as BROKKR__BROKER__PAK_HASH before first startup): 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
Day-zero flow: 1. export BROKKR__BROKER__PAK_HASH=9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08 2. Start the broker. First startup stores this hash on the admin role and the admin generator; no key file is written to /tmp/brokkr-keys/. 3. Authenticate with the PAK above. It cannot be recovered from the hash, so the hash is safe to keep in config while the PAK stays secret.The hash is printed as bare hexadecimal — exactly 64 characters, with no sha256: or other prefix. Copy it verbatim; the broker validates the configured hash at startup and refuses to boot with “Invalid PAK hash provided in configuration” if it is anything other than 64 hex characters.
See the Environment Variables Reference for BROKKR__BROKER__PAK_HASH.
brokkr-agent
Section titled “brokkr-agent”The agent binary runs in each target Kubernetes cluster and polls the broker for deployment objects to apply.
Commands
Section titled “Commands”brokkr-agent start
Section titled “brokkr-agent start”Starts the agent process.
brokkr-agent startHealth endpoints exposed on agent.health_port (default: 8080):
| Path | Purpose |
|---|---|
/healthz |
Liveness probe (always 200 OK) |
/readyz |
Readiness probe (checks Kubernetes API connectivity only) |
/health |
Detailed health status (JSON) |
/metrics |
Prometheus metrics |
A new agent is inactive. A new agent starts INACTIVE and applies nothing. On each poll while it is not ACTIVE, the agent logs one line at info level that names the fix:
Agent 'prod-1' (id: a1b2c3d4-e5f6-7890-abcd-ef1234567890) is INACTIVE. It applies nothing until an admin activates it. To activate it, run: brokkr agent activate prod-1An admin activates it with brokkr agent activate.
Generator scope self-registration (optional):
On startup the agent registers itself with the generator scopes it resolves, in precedence order:
| Precedence | Source | Notes |
|---|---|---|
| 1 | --generator-ids <csv> flag |
Comma-separated UUIDs. |
| 2 | BROKKR__AGENT__GENERATOR_IDS (config key agent.generator_ids) |
Comma-separated UUIDs, or a YAML list in the config file. |
| 3 | BROKKR_GENERATOR_IDS |
Deprecated legacy bare variable; still honored, logs a warning. |
Malformed UUIDs are skipped with a warning. An agent must be registered with a generator before any of that generator’s stacks can be targeted at it.
Agents are registered with the system generator (the fleet scope) at creation time, by both POST /api/v1/agents and brokkr-broker create agent — this setting only adds application scopes on top. An agent with no scopes set therefore has the system/fleet scope only. See Generator Registration and BROKKR__AGENT__GENERATOR_IDS.
Configuration
Section titled “Configuration”Both server binaries (brokkr-broker and brokkr-agent) read configuration from the same layered system (the brokkr client is configured separately — see the brokkr section):
- Embedded defaults (
default.tomlcompiled into the binary) - Configuration file (optional; path from
BROKKR_CONFIG_FILE) - Environment variables (prefix:
BROKKR__, separator:__)
For the server binaries there is no command-line flag for loading a configuration file; set the BROKKR_CONFIG_FILE environment variable instead (the brokkr client does take a --config flag). It loads the TOML file as a layer between embedded defaults and BROKKR__* environment variables, and additionally enables the broker’s file-change watcher used for hot-reload in Kubernetes (ConfigMap-mounted files).
See the Configuration Guide for all available settings and the Environment Variables Reference for the complete variable listing.
Exit Codes
Section titled “Exit Codes”| Code | Meaning |
|---|---|
| 0 | Clean shutdown, including graceful shutdown on SIGINT (Ctrl+C) |
| 1 | Command returned an error (e.g. server failed to bind, database error during a CLI command) |
| 101 | Startup panic (configuration, telemetry, or PAK-controller initialization failure) |
brokkr
Section titled “brokkr”brokkr is the control-plane client. It submits a folder of Kubernetes manifests as a stack’s desired state. It wraps the Rust SDK’s apply operation. It also does the day-zero steps: it activates, labels and lists agents, and labels, targets and lists stacks (see Day-zero commands).
Connection settings
Section titled “Connection settings”Every command resolves a broker URL and a PAK from three sources, in precedence order: command-line flag → environment variable → config file. A blank value in one source is treated as unset and falls through to the next.
| Setting | Flag | Environment variable | Config-file key |
|---|---|---|---|
| Broker URL | --broker-url <URL> |
BROKKR_BROKER_URL |
broker_url |
| PAK | --pak <PAK> |
BROKKR_PAK |
pak |
| Config-file path | --config <PATH> |
— | — |
The config file is TOML at ~/.brokkr/config by default (override with --config). A missing file is not an error; a present-but-malformed file is. Example:
broker_url = "https://broker.example.com"pak = "brokkr_BRabcd1234_GeneratorTokenExample0001"The broker URL may be given with or without the /api/v1 suffix — it is appended when absent and never doubled. The flags are global and may appear before or after the subcommand.
brokkr apply
Section titled “brokkr apply”Makes a folder of manifests the desired state of a stack, creating the stack if it does not exist. Idempotent: a re-run with an unchanged bundle submits no new revision and reports unchanged.
brokkr apply -f ./manifests --stack payments --target-label env:prodFlags:
| Flag | Required | Description |
|---|---|---|
-f, --filename <PATH> |
yes | Folder of manifests (top-level *.yaml/*.yml, sorted) or a single file. |
--stack <NAME> |
yes | Stack name; created if absent. |
--target-label <LABEL> |
no | Targeting label for agent fan-out (e.g. env:prod). Repeatable. |
--generator <NAME_OR_ID> |
with an admin PAK | The tenant that owns the stack, by name or id (the API calls a tenant a generator). Required with an admin PAK. Optional with a tenant PAK, where it must name the tenant of that PAK. |
With a tenant PAK, the tenant of that PAK owns the stack. With an admin PAK, the tenant named in --generator owns the stack; without it, the command exits 1 with an error that names the flag. It prints one of three lines and exits 0:
| Output | Meaning |
|---|---|
created stack "<name>": first revision (sequence <n>) |
Stack and its first deployment object were created. |
updated stack "<name>": new revision (sequence <n>) |
Bundle changed; a new deployment object was submitted. |
unchanged: stack "<name>" already current |
Latest deployment object already matches the bundle; nothing submitted. |
On any error (no connection settings, malformed config, unreadable bundle, broker rejection) the command prints error: <message> to stderr and exits 1.
brokkr register
Section titled “brokkr register”Registers an agent with a tenant for the agent. An agent must be registered with a tenant before any of the stacks of that tenant can target it. Agents normally self-register on startup (see brokkr-agent start); use this to register an agent before it is live, or to add a tenant. Requires an admin PAK. You can run this command again: if the agent is registered with the tenant already, the command changes nothing and exits 0, the same as brokkr agent label. The API still returns 409 already_registered for a repeat; the CLI shows it as unchanged:.
brokkr register --agent <NAME_OR_ID> --generator <NAME_OR_ID>Flags:
| Flag | Required | Description |
|---|---|---|
--agent <NAME_OR_ID> |
yes | The agent to register, by name or id. |
--generator <NAME_OR_ID> |
yes | The tenant to register it with, by name or id (the API calls a tenant a generator). |
The CLI finds each name or id in the same way as brokkr agent and brokkr stack. An id is used as it is. A name is looked up in the agent list or the tenant list. If two agents have the same name (in different clusters), the command stops and lists their ids; give the id instead. For example:
brokkr register --agent prod-1 --generator payments-teamregistered agent "prod-1" (6b1f...) with tenant "payments-team" (e5fe...) (registration 0c7d...)It prints one of two lines and exits 0:
| Output | Meaning |
|---|---|
registered agent <agent> with tenant <tenant> (registration <id>) |
The broker added the registration. |
unchanged: agent <agent> is registered with tenant <tenant> already |
The registration exists already. The broker changed nothing. |
On an error, the command prints error: <message> to stderr and exits 1.
See Generator Registration for the model and Agent registration for the operational guide.
brokkr deregister
Section titled “brokkr deregister”Removes an agent’s registration from a tenant. Requires an admin PAK.
brokkr deregister --agent <NAME_OR_ID> --generator <NAME_OR_ID>Flags:
| Flag | Required | Description |
|---|---|---|
--agent <NAME_OR_ID> |
yes | The agent to deregister, by name or id. |
--generator <NAME_OR_ID> |
yes | The tenant to remove the agent from, by name or id. |
The lookup is the same as for brokkr register.
Destructive: the broker also removes the agent’s agent_targets for the stacks of that tenant and pushes a target-changed frame to the agent, which prunes the corresponding Kubernetes resources on its next reconcile.
If the agent is not registered with the tenant, the broker removes nothing and returns success. The command prints the same deregistered line and exits 0.
brokkr registrations
Section titled “brokkr registrations”Lists the tenants that one agent is registered with, or the agents registered with one tenant. Exactly one of --agent or --generator is required. Cross-entity queries require an admin PAK.
# Tenants an agent is registered withbrokkr registrations --agent <NAME_OR_ID>
# Agents registered with a tenantbrokkr registrations --generator <NAME_OR_ID>Flags:
| Flag | Required | Description |
|---|---|---|
--agent <NAME_OR_ID> |
one of¹ | List the tenant registrations of the agent, given by name or id. |
--generator <NAME_OR_ID> |
one of¹ | List the registered agents of the tenant, given by name or id. |
¹ Exactly one of --agent or --generator must be given (mutually exclusive).
A name lookup reads the agent list or the tenant list. Only an admin PAK can read the tenant list. With an agent PAK or a tenant PAK, give the id. An id is used as it is, with no lookup.
Day-zero commands: brokkr agent and brokkr stack
Section titled “Day-zero commands: brokkr agent and brokkr stack”These commands do the first steps for a new agent or stack: activate the agent, add labels, target a stack at an agent, and list what the broker has. Each command takes an agent or a stack by name or id. The CLI looks up the id for you, so you do not need curl and jq to find it. An id matches first. If two agents have the same name, the command stops and prints their ids; give the id in its place.
Every command that adds something is safe to run again. If the label or the target exists already, the command prints a line that starts with unchanged: and exits 0. On an error, the command prints error: <message> to stderr and exits 1. A label that does not have the form key:value is a usage error: the command exits 2 and sends nothing to the broker.
| Command | PAK | What it does |
|---|---|---|
brokkr agent activate <AGENT> |
admin | Sets the agent status to ACTIVE. |
brokkr agent pause <AGENT> |
admin | Sets the agent status to INACTIVE. |
brokkr agent label <AGENT> <LABEL> |
admin | Adds a label to the agent. |
brokkr agent list |
admin or tenant | Lists the agents. |
brokkr stack label <STACK> <LABEL> |
admin or owning tenant | Adds a label to the stack. |
brokkr stack target <STACK> <AGENT> |
admin or owning tenant | Sends the stack to the agent. |
brokkr stack list |
admin or tenant | Lists the stacks. |
brokkr agent activate
Section titled “brokkr agent activate”Lets an agent apply its stacks. A new agent starts INACTIVE and applies nothing. While it is INACTIVE, the agent logs this at info level on each poll and names this command. After you activate it, the agent applies its stacks on its next poll.
brokkr agent activate prod-1agent "prod-1" (a1b2c3d4-e5f6-7890-abcd-ef1234567890) is ACTIVE. It applies its stacks on its next poll.This is the same as PUT /api/v1/agents/{id} with {"status": "ACTIVE"}.
brokkr agent pause
Section titled “brokkr agent pause”Stops an agent from applying its stacks. The command sets the status to INACTIVE. The agent keeps the resources that it applied, but it applies no new changes until you activate it again.
The agent stops its own work. The agent reads its status from the broker on each heartbeat. While the status is not ACTIVE, the agent does not fetch deployment objects, work orders, health checks, diagnostics or webhook deliveries. It continues to send heartbeats. The broker does not check the status: it serves deployment objects to an INACTIVE agent that asks for them. Thus INACTIVE is not an access control. To stop an agent that you do not trust, revoke or rotate its PAK (Prefixed API Key). See Agent Status Is Not an Access Control.
brokkr agent pause prod-1agent "prod-1" (a1b2c3d4-e5f6-7890-abcd-ef1234567890) is INACTIVE. It applies nothing until you run: brokkr agent activate prod-1brokkr agent label
Section titled “brokkr agent label”Adds a label to an agent. A stack that has the same label goes to the agent. The label has the form key:value, for example env:prod. It can have up to 64 characters and no spaces. See The label shape.
brokkr agent label prod-1 env:prodadded label "env:prod" to agent "prod-1"The API form is POST /api/v1/agents/{id}/labels with {"agent_id": "<id>", "label": "env:prod"}. The body repeats the agent id.
brokkr agent list
Section titled “brokkr agent list”Lists the agents with their name, id, status, cluster and labels. An admin PAK lists all agents. A tenant PAK lists only the agents that are registered with its tenant. The broker does not show agent labels to a tenant PAK, so that list has no LABELS column.
brokkr agent listNAME ID STATUS CLUSTER LABELSprod-1 a1b2c3d4-e5f6-7890-abcd-ef1234567890 ACTIVE us-east-1 env:prod,region:us-eaststage-1 0f9e8d7c-6b5a-4321-9876-543210fedcba INACTIVE us-west-2 -brokkr stack label
Section titled “brokkr stack label”Adds a label to a stack. The stack goes to each agent that has the same label. The label shape is the same as for agents.
brokkr stack label payments env:prodadded label "env:prod" to stack "payments"brokkr apply --target-label env:prod adds the same label when it applies a folder.
brokkr stack target
Section titled “brokkr stack target”Sends a stack to one agent, whatever the labels of the agent are. The first argument is the stack; the second is the agent.
brokkr stack target payments prod-1targeted stack "payments" at agent "prod-1"The agent must be registered with the tenant that owns the stack. If it is not, the broker refuses the target, and the error gives the command that registers it:
error: invalid request: agent "prod-1" is not registered with the tenant that owns stack "payments". Register it first: brokkr register --agent <agent-id> --generator <generator-id>The API form is POST /api/v1/agents/{id}/targets with {"agent_id": "<id>", "stack_id": "<id>"}. The body repeats the agent id.
brokkr stack list
Section titled “brokkr stack list”Lists the stacks with their name, id and labels. An admin PAK lists all stacks. A tenant PAK lists the stacks of its tenant.
brokkr stack listNAME ID LABELSpayments c4ba105f-4332-447b-8af5-63f8e69ee89c env:prodExamples
Section titled “Examples”# Start broker with environment overridesBROKKR__DATABASE__URL=postgres://user:pass@db:5432/brokkr \BROKKR__LOG__LEVEL=info \BROKKR__LOG__FORMAT=json \ brokkr-broker serve
# Create an agent and capture its PAKbrokkr-broker create agent --name prod-1 --cluster-name us-east-1 2>&1 | grep "Initial PAK"
# Create an agent already registered with two application scopesbrokkr-broker create agent --name prod-1 --cluster-name us-east-1 \ --generator-ids f8e7d6c5-b4a3-2109-8765-432109876543,a1b2c3d4-e5f6-7890-abcd-ef1234567890
# Start agent with environment configBROKKR__AGENT__BROKER_URL=https://broker.example.com \BROKKR__AGENT__PAK=brokkr_BRx9y2Kq_A1B2C3D4E5F6G7H8I9J0K1L2 \BROKKR__AGENT__AGENT_NAME=prod-1 \BROKKR__AGENT__CLUSTER_NAME=us-east-1 \ brokkr-agent start
# Start agent and self-register with a generator scopeBROKKR__AGENT__BROKER_URL=https://broker.example.com \BROKKR__AGENT__PAK=brokkr_BRx9y2Kq_A1B2C3D4E5F6G7H8I9J0K1L2 \BROKKR__AGENT__AGENT_NAME=prod-1 \BROKKR__AGENT__CLUSTER_NAME=us-east-1 \BROKKR__AGENT__GENERATOR_IDS=f8e7d6c5-b4a3-2109-8765-432109876543 \ brokkr-agent start