Wheelhouse docs

Issue a token for automation#

You will end up with a bearer token for one script, one CI job or one monitoring system, carrying the lowest role that works and an expiry date. Use a token rather than a cookie for anything scripted: token requests skip the CSRF header requirement that browser sessions have.

Before you start#

  • The admin role.
  • A decision about which consumer this is for, and what role it needs. One token per consumer, always — a shared token cannot be revoked without breaking everything at once.

Step 1 — Issue it#

Administration → API tokens → + Add token.

bash
R=https://<router>:8443
T=wh_...                                    # an admin token, or a session
curl -sk -X POST -H "Authorization: Bearer $T" -H 'Content-Type: application/json' \
  -d '{"label":"prometheus","role":"viewer","expires_days":365}' "$R/api/admin/tokens"
json
{
  "id": "a1b2c3",
  "token": "wh_…",
  "expires_at": "2027-09-02T00:00:00Z",
  "note": "copy this now — it is not recoverable"
}

The token begins wh_, which is deliberate: it makes a leaked one findable by a secret scanner and greppable in a log.

expires_days is optional; without it the token does not expire, which is almost never what you want.

Step 2 — Give it the lowest role that works#

ConsumerRole
Prometheus, a dashboard, a health checkviewer
A script that stages and commits, a reconcile joboperator
Account management, boot images, the licenceadmin

A token's role is fixed at creation. To change it, issue a new one and revoke the old.

Step 3 — Store it as a secret#

In whatever your automation already uses for secrets. Not in a repository, not in a crontab, not in a shell alias.

On the router itself, the agent's own secret files are mode 0600 and the agent refuses to read a secret file that is group- or world-readable — the same standard is worth applying to wherever this token ends up.

Step 4 — Use it#

bash
R=https://<router>:8443
T=wh_...
curl -sk -H "Authorization: Bearer $T" "$R/api/system"

That is the whole convention, and it is the one every guide here uses.

Check it worked#

bash
curl -sk -H "Authorization: Bearer $T" "$R/api/auth/me"

That returns the principal, its role and its capabilities — which is the fastest way to confirm a token has the role you meant to give it.

Administration → API tokens lists every token with its label, its role, who created it, when it was last used and when it expires. Last used is the column to read when you are deciding whether a token is still needed.

Revoking#

bash
curl -sk -X DELETE -H "Authorization: Bearer $T" "$R/api/admin/tokens/a1b2c3"

The page's row delete stages the same. Revoke a token when:

  • the consumer goes away;
  • the person who created it leaves — a token outlives the account that created it;
  • you suspect it has leaked. Immediately, and then find out.

See also#


Checked against agent/admin.go · agent/auth.go · ui/src/pages/Tokens.tsx · docs/security.md

Updated 2026-09-02 tokens automation api