Keep API tokens safe and review the sign-in log
An API token is a password for a script. Anyone who holds one can do whatever its scopes allow, from anywhere, without two-factor and without your browser. Tokens leak through logs, screenshots, shared chats and public repositories far more often than passwords do, so a little routine pays for itself.
This article gives you a practical routine: how to create tokens that cause little damage if they leak, how to review the list, how to rotate a token without downtime, how to revoke one in an emergency, and where to look for signs of misuse.
Before you begin
- A token or two. If you have none yet, read Create an API token and pick scopes.
- A list of what uses each token. CI jobs, scripts, monitoring dashboards. You cannot rotate or revoke what you cannot find, so write it down, in the token's name if nowhere else.
- Access to the tools that hold the token, such as your CI provider's secret store, so you can replace it in one go.
Tokens are personal: each belongs to the member who created it, works in one organisation and can never do more than that member's role allows. If a member leaves the organisation or is demoted, their tokens lose access on the next call. Prefer a token created by a person who will stay, or by a shared service account (a member created for the purpose), over one tied to someone who is about to leave.
1. Create tokens that limit the damage
Four decisions at creation time matter more than anything you do later.
- Name. One token for one job, named after the job:
GitHub Actions deploy shop, nottoken2. The name appears in the list, in the revoke prompt and in the activity log, which is what lets you work out which token a log line belongs to. - Expires. 30 days, 90 days, 1 year, 10 years (default) or Never. The default is ten years, which is almost never what you want. Pick 90 days or one year for anything automated and put the renewal in your calendar. A leaked token that expires next month is a smaller problem than one that lives for a decade.
- Scopes. Start from Read-only and add only the write scopes the job needs. A deploy pipeline needs
sites:viewandsites:manage-deploys, notFull. Reading or writing the.envfile needs the separatesites:manage-environmentscope, so a deploy token never sees secrets.
Never share one token between jobs. When one leaks you would have to replace it everywhere, and you could not tell which job leaked it.
2. Review the list every month
Open Settings > API tokens.
- Scopes. The number of permissions each token carries. A token with dozens of scopes for a one-line job is a candidate for replacement.
- Last used. When the token last made a request, or Never used. A token that has not been used for months belongs to a job that no longer exists: revoke it. A token that is used when nothing should be running needs investigating (see step 5).
The Expires column shows when each token ends, or Never, and an expired token carries a red Expired badge. Hover over the value for the exact date and time. An expired token is already useless, but remove it from the list and from the tool that still holds it.
The list shows only the last four characters of each secret (srv_…75jA). That is enough to recognise a token you copied, and never enough to use it. SrvYard keeps only a hash of the full token.
3. Rotate a token
A token has no "edit" or "renew": scopes and expiry are fixed when it is created. Rotation means creating a new one and retiring the old, in this order so nothing breaks:
- Create the new token with the same scopes (or fewer) and a fresh expiry. Copy it when the dialog shows it; it is displayed only once.
- Store it where the job reads it, for example the secret of your CI provider. Replace the old value.
- Run the job once and check that it works. In the token list, the new token's Last used changes from Never used to a recent time.
- Revoke the old token (next step) once its Last used has stopped changing.
Test the new token with the call that says who you are, which needs no scope: GET /api/v1/token returns the name, the organisation, the scopes and the expiry. See API conventions.
4. Revoke a token
Open the actions menu (the three dots) at the end of the row and choose Revoke.
- Cancel. Leaves the token alone.
- Revoke token. "Anything using this token stops working immediately. This cannot be undone." The next request with it is answered
401, and SrvYard records that you revoked it.
If you suspect a token leaked, revoke first and investigate afterwards. Revoking takes a second; a deployed script that suddenly fails is easy to fix with a new token.
If the leak was in a Git repository, revoke the token and also remove it from the history of the repository, or treat it as public forever. Anything that was pushed to a public host has been copied.
5. Look for signs of misuse
Three places tell you what a token, or an account, has been doing.
The sign-in log of your account. For the account itself, open Settings > Security and choose View full sign-in history (Auth Log).
- When. Newest first. Compare the times with when you were working.
- Location. The IP address of the attempt. SrvYard does not look up a country, so compare the address with where you normally sign in from.
- Search. Filters by IP, method or reason.
A row marked Failed is an attempt that did not get in. A Success you do not recognise is a reason to change your password, end your sessions and check your tokens. See Turn on two-factor authentication and manage your sessions.
The activity of the organisation. Everything a token changes is recorded with the actor token:<name> (for example token:GitHub Actions deploy shop), without the request body. The server and site Activity tabs show the last 14 days of what happened, and the same feed is available through the API with the scope activity:view. If you see a deployment or a change at a time nobody was working, find the token named there.
The token list itself. Last used is updated at most once a minute. An unexpected recent value on a token that should be idle is your clearest signal.
6. Make the routine stick
- Name tokens so an old one is obvious, for example with the year:
deploy shop 2026. - Prefer short expiries and renew on a schedule; an expired token cannot leak anything.
- Keep secrets out of reach: CI secrets, never code, never chat. Rotate the moment someone who knew a token leaves.
- Limit who can create tokens. Creating tokens needs the
tokens:managepermission. In an organisation with strict needs, create a custom role without it. See Least privilege and auditing. - Use the plan's limits as a feature. The API is rate-limited per token (60 requests a minute), so a runaway or abused token is slowed down on its own.
Troubleshooting
- A job suddenly fails with 401 after I revoked something. The job used that token. Create a new one, store it, and run the job again.
token_expired. The token passed its expiry date. Create a new one; expiry cannot be extended.- I do not know which job uses a token. Look at Last used, then at the activity feed for entries with that token's name around those times. If you still cannot tell, revoke it and see what breaks.
- A token I did not create appears in the list. The list shows only your own tokens, so you created it, or someone signed in as you. Revoke it, change your password and end your other sessions.
- I cannot create a token. The plan has no API, or your role lacks
tokens:manage. See Create an API token and pick scopes. - The Expires column says "just now" for a token that lives for years. The column shows future dates poorly. Hover for the exact date, or read
expires_atfromGET /api/v1/token.
Related
- Create an API token and pick scopes: the creation flow in detail.
- API conventions: authentication, errors and rate limits.
- Turn on two-factor authentication and manage your sessions: protect the account behind the tokens.
- Least privilege and auditing: who may create tokens in the first place.