Per-station enrolment keys: credentials for CI runners and test benches
Why Bud gives every Test Station its own key, shown once and pinned to the first station that uses it.
Campaign week 3 · Bud TMP
A test results server trusts whatever posts results to it. Early versions of Bud used one shared registration secret for every runner. That is simple, and it is the wrong model: a secret copied onto every bench and CI image cannot be revoked for one machine, and anyone holding it can register anything.
One key, one station
Section titled “One key, one station”In Bud an administrator opens Test Stations and creates an enrolment key, naming the station it is for, for example hil-bench-01 or ci-linux-01. Then:
- The key is shown once, on creation, and is never retrievable afterwards.
- It pins to the first station that registers with it. From then on only that station can use it.
- The name comes from Bud, not from the machine: whatever
--usernamethe bench passes, it takes the name the administrator gave the key. A later rename in Bud reaches the station on its next heartbeat.
On the machine:
export RUNNER_API_KEY="the-key-you-minted"python -m bud_runner register --username ci-linux-01 --socket-port 53035python -m bud_runner daemon --username ci-linux-01 --location "GitHub Actions · self-hosted"The runner keeps its identity and tokens in ~/.bud/, a vault that never belongs in a repository. Non-secret context such as the backend URL can live in app.properties.
Revocation that matches reality
Section titled “Revocation that matches reality”Because each station has its own key, revoking one key or removing one station affects only that machine. Removing a station revokes its credentials and keeps every run it produced, so the evidence survives the hardware.
Heartbeats and availability
Section titled “Heartbeats and availability”A registered daemon reports a heartbeat with its location. The Test Stations page shows which stations are online and ready, which suites a station has run, and any queued custom runs, so the person queueing a run knows a station will pick it up.
Self-hosted CI runners register like benches. A job then runs the suite through bud-runner; results go to Bud under that station’s identity, and JUnit XML is still written for the pipeline. If you prefer short-lived credentials from your CI provider, tell us: OpenID Connect sign-in is on the roadmap.


