Watching what a key does
Open Settings → API keys and click a key’s Usage button. The panel shows two things:- Spend today against that key’s daily limit, with the reset time. If the key has no limit, you get the figure without a progress bar — a percentage of nothing would be either always empty or always full, and both would be lies.
- The rentals this key started, newest first, with their status.
A revoked key keeps its usage panel. What it spent before you turned it off is
exactly the thing you want to see afterwards — that is usually why you are
looking.
On the Instances page
Rentals started through the API carry an API badge, and the Via API filter narrows the list to them. A machine you did not start by hand still spends the same wallet and still occupies a slot under the concurrency ceiling; without the badge it reads as something you forgot doing.From your own code
GET /rentals is the account’s whole rental list, so it answers “what is running”
but not “which key started it” — attribution lives in the dashboard.
key_id from GET /me at startup and
attach it to the rentals you create. It is not a secret.
Rotation
Rotate on a schedule — quarterly is a reasonable default — and always after someone with access leaves.1
Mint the replacement
Same scopes, a name that distinguishes it:
prod-scheduler-2026q3.2
Deploy it
Both keys are valid at once, so there is no downtime window to coordinate.
3
Watch the old key go quiet
Its usage panel should stop gaining rentals. A key that is still busy is a
deployment you have forgotten about — find it before you revoke, not after.
4
Revoke the old key
Immediate, and final.
If a key leaks
A key in a public repository, a screenshot, a shared log file, or a chat message is compromised. Treat “probably nobody saw it” as “someone did” — automated scrapers find committed credentials within minutes.Revoke it now
Settings → API keys → Revoke. Effective on the next request. Do this before
you investigate; the investigation keeps, the exposure does not.
2
Stop what it started
Revoking the key does not stop its rentals. They belong to the account and
keep billing. Filter the Instances page by Via API, check the key’s usage
panel for what it started, and stop anything you do not recognise.
3
Check the ledger
Billing → transaction history. You are looking for top-ups you did not make and
rentals you did not start.
4
Mint a replacement and redeploy
New key, narrowest scopes that work, and a spend limit if
it can rent.
5
Purge the exposure
Rewriting git history is not enough on its own — the old commit may already be
cached by GitHub or cloned. Revocation is what makes the leaked string worthless;
history rewriting is tidying up afterwards.
Hygiene checklist
Never ship a key to a client
Never ship a key to a client
Browsers, mobile apps and desktop binaries are all readable by their users. There
is no minification, obfuscation or CORS setting that changes this. If a browser
needs GPU Outlet data, proxy it through your own backend and keep the key there.
Environment, not source
Environment, not source
GPUOUTLET_API_KEY from the environment or a secret manager. Not a literal, not
a committed .env, not a default value in a config file. Add .env to
.gitignore before the first commit, not after the first leak.Keep keys out of logs
Keep keys out of logs
The common accident is logging the whole request, headers included. Redact
Authorization in your logging middleware.Note that we never put credentials in a URL — SSH and web-terminal passwords come
back as fields in access, not baked into a link — precisely so that logging a
URL cannot leak one. Extend the same courtesy to your own logs.Scope down, then cap
Scope down, then cap
Narrow scopes limit what a leak can do at all; a spend
limit bounds what it costs if it can rent. They are different
controls and worth having both.
One key per integration
One key per integration
So that revoking a compromised key does not take down three unrelated systems,
and so the usage panel tells you which integration is misbehaving.
What we do on our side
- We store only a SHA-256 hash of each key. A dump of our database yields no usable credentials.
- The dashboard shows a masked form (
gpk_live_YOUR…HERE) — enough to tell two keys apart, useless to a thief. - Keys carry a recognisable
gpk_prefix so secret scanners can match them. - Revocation is immediate, not eventually-consistent.
- Rate limits are enforced per key and per IP, so a stolen key cannot be used to hammer the API from a thousand hosts at once.