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 browser session for anything scripted: a request with a token needs no CSRF header, which a browser session must send with every change.

Before you start#

  • The Admin role. The Admin group of the navigation is shown to administrators only.
  • A decision about which system this is for, and what role it needs. One token per system, always — a shared token cannot be revoked without breaking everything that uses it at once.

Step 1 — Issue it#

Admin → API tokens → Issue token.

FieldTakes
Label"Name the system that will use this token." — prometheus, terraform-prod.
RoleViewer: reads everything, Approver: applies changes others prepare, Operator: prepares and applies changes or Admin: also manages users, tokens and settings.
ExpiresNever, In 30 days, In 90 days or In a year.

Choosing Admin adds a warning: "An admin token can add users and issue more tokens."

Issue token creates it at once; tokens are not pending changes. A panel headed New token: and the label shows the token under "Copy the token now. It is not shown again." Copy it before you choose Done. With Advanced mode on, the panel also shows an example request.

The token begins wh_, which makes a leaked one findable by a secret scanner and in a log.

Choose an expiry: a token set to Never stays valid until somebody revokes it. An expired token is refused like a revoked one.

Step 2 — Give it the lowest role that works#

ConsumerRole
Prometheus, a dashboard, a health checkViewer
A script that prepares changes and applies them, a reconcile jobOperator
Users, the licence, system imagesAdmin

A token's role is fixed when it is issued. 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 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.

Check it worked#

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

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

Admin → API tokens lists every token with its label, ID, role, who issued it, when, when it was last used and when it expires; an expiry less than a week away is shown in amber. Last used is the column to read when you are deciding whether a token is still needed.

In the audit log (System → Audit log tab) the token's issue is "Issued an API token", with its label and role beneath it, and every action the token takes is recorded under token: and its label.

Revoking#

Revoke on the token's row asks "Revoke prometheus?". The second click revokes it at once, and anything using the token stops working immediately.

Revoke a token when:

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

Issuing and revoking from a script#

With an admin token:

bash
R=https://<router>:8443
T=wh_...                                    # an admin token
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": "3f9a1c0b7e2d",
  "label": "prometheus",
  "role": "viewer",
  "token": "wh_…",
  "expires_at": "2027-09-18T09:00:00Z",
  "note": "copy this now — it is not recoverable"
}

expires_days is optional; without it the token does not expire. To revoke, use the id:

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

See also#

Updated 2026-09-18 tokens automation api