Wheelhouse docs

Every flag#

wheelhouse-agent registers 51 flags. Every subcommand shares the whole set, so a flag that means nothing to plan is accepted and ignored rather than refused.

Re-derive the list for the version you are running:

bash
grep -E '^\tflag\.(String|Bool|Int|Duration)Var' agent/main.go

Router connection#

FlagDefaultWhat it does
--api-urlhttps://127.0.0.1Base URL of the router's own HTTP API. A trailing slash is trimmed. On an appliance this is loopback, because first boot pins the router API to loopback.
--api-key$VYOS_API_KEYThe router API key. Root-equivalent on that router. Prefer the file form.
--api-key-file—File holding the key. Required to exist when given: a missing file here is fatal, unlike the other four secret files.
--demofalseStart with no router credentials at all. Every router read then fails; the UI still loads. Also disables the cache primer.

Either --demo, or both a non-empty --api-url and a non-empty API key, are required. Without them the agent logs either --demo or both --api-url and --api-key are required and exits 2.

Listener#

FlagDefaultWhat it does
--addr127.0.0.1:8090Listen address. The shipped systemd unit overrides this to 0.0.0.0:8443 — every interface, including the WAN.
--ui-dir—Directory of built UI files. Empty means no GET / route at all: the API answers, the browser gets a 404. The package installs the UI at /usr/share/wheelhouse/ui.
--trust-proxyfalseTrust X-Forwarded-For and X-Forwarded-Proto. Only behind a reverse proxy you control — without it, a client could forge its own address into the audit log and around the per-address login rate limit. The last element of the header is the one used.
--metrics-publicfalseServe GET /metrics with no authentication. Off by default, where the route needs the viewer role.

Data and state#

FlagDefaultWhat it does
--data-dir/config/wheelhouseEverything the agent persists: state.json, audit.jsonl, the self-signed certificate, initial-password. Created at mode 0700 if missing. On VyOS, /config survives an image upgrade and /var/lib does not.
--fleet-config—JSON file listing other routers. Loaded whatever the licence says; the fleet endpoints answer 402 until a licence whose plan includes fleet is held. The file must be mode 0600 or the agent exits 1.

Only one agent may hold a data directory at a time. A second one exits 1 with another agent is running against this data dir.

TLS#

FlagDefaultWhat it does
--tls-cert—Certificate file. Must be given together with --tls-key; one without the other is a startup error.
--tls-key—Private key file.
--tls-self-signedfalseGenerate agent.crt / agent.key in the data directory when --tls-cert is not set and no usable pair is already there.

The generated certificate is a server leaf, not a CA: P-256 ECDSA, 398 days, DigitalSignature + ServerAuth, IsCA: false, with SANs for the host name, <host>.local, localhost, 127.0.0.1, ::1 and every non-loopback address on the box. An existing certificate is replaced on sight if it is unreadable, if it was generated as a CA, or if it expires within 30 days.

Serving on a non-loopback address with no certificate logs a warning naming the three fixes. See Ports and listeners.

Authentication and the first account#

FlagDefaultWhat it does
--admin-token$WHEELHOUSE_ADMIN_TOKENBreak-glass Bearer token, admin role, no account behind it. Prefer the file form.
--admin-token-file—File holding it. A missing file degrades to "no break-glass" with a warning rather than aborting startup.
--initial-adminadminUser name created on the first start with an empty state file.
--initial-admin-password$WHEELHOUSE_INITIAL_PASSWORDPassword for that account. Empty means the agent generates one, logs it once and writes it to <data-dir>/initial-password at 0600.
--initial-admin-password-file—File holding it; overrides the flag.

All three initial-account flags are read only when the state file has no users. Any non-empty password is accepted; an empty one, or one over 1024 characters, is refused. The account is flagged must change password either way.

Licensing#

FlagDefaultWhat it does
--license-key$WHEELHOUSE_LICENSEThe licence key. A key given here is also saved into the state file, so the next start without the flag still holds it.
--license-key-file—File holding it.
--license-serverhttps://license.rhymelikedi.meWhere the daily refresh goes. An empty value disables the refresh entirely and runs on the offline path.

Without a usable licence every mutating endpoint answers 402 and every read keeps working. See Licence keys and states.

Single sign-on#

Everything here is optional. An agent with no issuer keeps password, TOTP, token and break-glass logins.

FlagDefaultWhat it does
--oidc-issuer$WHEELHOUSE_OIDC_ISSUERIssuer URL, e.g. https://auth.example.com/application/o/wheelhouse/. Must be an absolute http(s) URL.
--oidc-client-id$WHEELHOUSE_OIDC_CLIENT_IDClient id.
--oidc-client-secret$WHEELHOUSE_OIDC_SECRETClient secret. Prefer the file form.
--oidc-client-secret-file—File holding the secret.
--oidc-redirect-urlderived per requestThe exact /api/oidc/callback URL registered at the provider. When given it must be a full URL ending in /api/oidc/callback.
--oidc-scopesopenid profile email groupsSpace-separated scopes to request.
--oidc-username-claimpreferred_usernameClaim used as the local user name when provisioning: preferred_username, email, name or sub.
--oidc-groups-claimgroupsClaim holding group membership.
--oidc-admin-groups—Comma-separated groups mapped to the admin role. Empty means no group mapping at all.
--oidc-operator-groups—Comma-separated groups mapped to the operator role.
--oidc-default-roleviewerRole for a provisioned user outside every mapped group. Must be viewer, operator or admin.
--oidc-provisiontrueCreate a local account on the first sign-on for an unknown identity.
--oidc-link-by-emailfalseLink an identity to an existing account by email — and only when the provider asserts email_verified.
--oidc-labelAuthentikProvider name shown on the login screen.
--oidc-ca-file—PEM root CA to trust for the issuer instead of the system trust store.
--oidc-post-logout-redirect—Registered post-logout URI to send the browser to at the provider.

Single sign-on is "configured" only when both --oidc-issuer and --oidc-client-id are set. The agent exits 2 at startup on any of these:

  • --oidc-issuer without --oidc-client-id, or the reverse;
  • an issuer that is not an absolute http(s) URL;
  • a configured provider with no client secret;
  • a --oidc-redirect-url that does not end in /api/oidc/callback;
  • an invalid --oidc-default-role;
  • --oidc-provision together with --oidc-username-claim=sub, which would name every account after a UUID.

When it validates, the agent logs one line at start naming the issuer, client id, redirect URI, provisioning and default role. Compare it with the registration at the provider.

Desired state (plan and apply)#

FlagDefaultWhat it does
--file<data-dir>/agent.yamlThe desired-state document. JSON or YAML, chosen by what the bytes look like rather than by the extension.
--fullfalseFull mode: also emit delete for live nodes the file does not declare.
--jsonfalseWith plan: emit a JSON document instead of command lines.
--commitfalseWith apply: commit instead of staging. Requires --confirm-minutes.
--confirm-minutes0The commit-confirm window for --commit. apply --commit refuses to run at 0.
--agent-url—With apply: the running agent to stage through, e.g. https://127.0.0.1:8443. Needs --admin-token or --admin-token-file.

The reconcile loop#

Off unless --reconcile-file is set. It is a writer, so it obeys the same licence gate as the Commit Bar and pauses without one.

FlagDefaultWhat it does
--reconcile-file—Keep the router aligned with this desired-state file. Empty means the loop never runs.
--reconcile-modestagestage puts the difference in the Commit Bar and waits for a person; commit applies it. Any other value is a startup error (exit 2).
--reconcile-interval60sHow often the loop re-diffs. Values below the 10 s floor are clamped, with a warning naming what you asked for.
--reconcile-delay15sHow long after start the first pass waits.
--reconcile-confirm2Commit-confirm minutes used in commit mode. At 0 or below, the loop commits without a confirm window.
--reconcile-fullfalseRun the loop in full mode, which deletes what the file does not declare.

Diagnostics#

FlagDefaultWhat it does
--log-levelinfodebug, info, warn or error. An unparseable value silently becomes info.
--versionfalsePrint wheelhouse-agent <version> and exit 0. Identical to the version subcommand.

What the shipped unit passes#

The appliance's systemd unit uses ten of these and nothing else:

--api-url https://127.0.0.1
--api-key-file /config/wheelhouse/api-key
--admin-token-file /config/wheelhouse/admin-token
--license-key-file /config/wheelhouse/license-key
--addr 0.0.0.0:8443
--tls-self-signed
--ui-dir /usr/share/wheelhouse/ui
--data-dir /config/wheelhouse
--log-level info

It sets no OIDC flags, so writing an oidc-secret file on its own configures nothing; turning single sign-on on means a drop-in that repeats ExecStart with the --oidc-* flags added. See systemd units.

See also#

Updated 2026-09-02 cli flags agent