API keys and machine credentials
A machine credential (API key) lets a script, CI job or the probe CLI call
the ProbeRun API without a person signed in. Manage them under Team → API
keys (admin role). The key value is shown once at creation.
Creating a key
- Give it a name and a role (
viewer,developer,admin). A key’s role is used only when the key is the sole credential on a request; when a key accompanies a signed-in member, the member’s role governs. - Expiry. Keys created now expire after 365 days by default. Pass an
explicit
expires_at, ornon_expiring: true, to change that. Expiry shows wherever keys are listed, and an expired key is refused exactly like a revoked one (credential_expired, audited). - Keys that predate the expiry feature are grandfathered non-expiring, and the operator’s health check names each one until it is rotated.
What a key looks like
Keys start with proberun_ and end in a checksum, so secret scanners can
recognise one in a commit or a log. The list never shows a whole key: it shows
the last four characters (proberun_…abcd) and who created it, which is enough
to tell keys apart. Keys created before this format show as “older key” and keep
working. On creation the dashboard shows the key once, masked, with Copy key,
Show key and Download .env (PROBE_API_KEY=…, plus PROBE_API_URL=…, commented out
when the deployment declares no public API URL).
Rotation
The quick way is Roll (Team → API keys, or POST /team/api-keys/{id}/roll):
it mints a replacement with the same name, role and lifetime length and revokes
the old key in one step. There is no grace period, so update every consumer
straight after. Created by still names the original creator; who rolled it is
in the audit log. A revoked or expired key cannot be rolled (409); create a new
one instead.
To move consumers over before the old key stops working:
- Create the new key.
- Move each consumer to it.
- Revoke the old key (Team → API keys → revoke, or
DELETE /team/api-keys/{id}). Revocation is immediate and audited (credential_revoked).
If a key leaks, roll or revoke it.
What a key alone cannot do
Under federated login, the governance surfaces (/team/* and
/audit-events) require a signed-in person in addition to any key, so that
every governance action is attributable to someone. A script calling them with
a key alone receives 401 identity_assertion_required. Run such scripts as a
signed-in member, or ask your operator about the temporary
AUTH_GOVERNANCE_KEY_GRACE=1 posture while you migrate.
The dashboard’s own service key is deliberately a non-admin credential for the same reason; it proves a trusted service is calling, not who the person is.
Running without a key
If your operator runs ProbeRun with sign-in off (AUTH=disabled) and no API key
configured, the API answers only callers on the same machine (loopback). A
request from anywhere else, a container included, gets 401 loopback_only
naming the fix: your operator sets PROBE_API_KEY (and gives the dashboard the
same value) or turns on federated login (AUTH=oidc). A forged
X-Forwarded-For: 127.0.0.1 header does not help: the API is launched with
proxy-header handling off, and refuses to start in this mode if it is told to
trust forwarded headers.
Behind any reverse proxy, use a key or federated login: a proxy on the same machine connects over loopback, so everything it forwards is served.
Rate limits
Each principal (member, key, or legacy key) gets 600 requests per minute by
default, and each client address 1,200, enforced before any credential check.
Responses carry X-RateLimit-Limit and X-RateLimit-Remaining; over the bound
is 429 with Retry-After. Your operator can change both.