Code & CI · Secret guide

Leaked GitHub Personal Access Token: what to do in the first hour

Critical severityChecked liveLast verified · 5 min read

A GitHub personal access token (PAT) is a password for the GitHub API and for git over HTTPS. Whoever holds it acts as you, within the scopes you gave it: reading private repositories, pushing code, editing workflows, even deleting repositories. If yours ended up somewhere public, revoke it first and investigate second. Deleting the commit does not help, because public commits are copied within minutes.

Check your GitHub account for leaked secrets — free

Provider
GitHub
Severity
Critical
Impact
Source code and build access
Checked live by LeakWatch
Yes
Revoke at
GitHub

What a GitHub personal access token looks like

GitHub tokens are recognizable by their prefix. Two families are personal access tokens:

ghp_…XXXX          classic personal access token (masked)
github_pat_…XXXX   fine-grained personal access token (masked)

The other prefixes are not PATs, although they are just as sensitive and are caught by the same rule: gho_ (OAuth app token), ghu_ (GitHub App user token), ghs_ (GitHub App installation token, which expires after about an hour) and ghr_ (refresh token). A classic token works on every repository you can reach, filtered only by scopes such as repo, workflow or delete_repo. A fine-grained token is limited to the repositories and permissions chosen at creation, so the damage depends on what was selected.

If what leaked is a GitLab token (glpat-), use the GitLab personal access token guide instead.

How GitHub tokens get leaked

  • Remote URLs with the token inside. git remote add origin https://<token>@github.com/... ends up in .git/config, in shell history, and in scripts that clone private repositories.
  • CI configuration and deploy scripts. A token pasted into a workflow file, a Dockerfile ARG, or a build log that prints the environment.
  • Package and tooling config. An .npmrc, a pip.conf or a Dockerfile that installs private dependencies from GitHub with the token in plain text.
  • Dotfiles and gists. A public dotfiles repository that includes a shell profile with export GITHUB_TOKEN=....
  • Pasted into an issue or chat while asking for help, often inside a command that was copied from a terminal.

What to do in the first hour

  1. Revoke the token. Open GitHub → Settings → Developer settings → Personal access tokens. Classic tokens are under Tokens (classic) and are removed with Delete; fine-grained ones are under Fine-grained tokens and are removed with Revoke. The list shows the name and last-used date but not the value, so match on the name and creation date. If you are unsure which one leaked, revoke every token you do not recognize. GitHub may also have revoked it already: its own secret scanning looks for tokens in public repositories, but do not count on that.
  2. Create a replacement with the least access that works. Prefer a fine-grained token limited to one repository, with an expiry date. In GitHub Actions, the built-in GITHUB_TOKEN usually removes the need for a PAT altogether.
  3. Read your security log. In Settings → Security log look for events since the exposure: new SSH or GPG keys, new tokens, new OAuth or App authorizations, changed email addresses. Attackers often add a second way back in.
  4. Check the repositories the token could reach. Look for unexpected commits, new branches, edited workflow files under .github/workflows, new deploy keys and new webhooks. If the token had repo scope on an organization, ask an organization owner to review the organization audit log as well.
  5. Rotate what the token could read. A token with access to private repositories also exposed every secret stored in them. Treat those as leaked and rotate them, starting with cloud keys.
  6. Re-authorize SSO if needed. On organizations with SAML single sign-on, tokens must be authorized per organization; revoking the token removes that authorization too.
  7. Then clean the repository: remove the value, rewrite history if you want to. The order of operations is in I accidentally pushed an API key to GitHub.

Not sure whether other secrets leaked from the same account? Run a free scan and see everything exposed under your username.

Not sure what else leaked? Run a free scan.

Revoke it at GitHub

Go to github.com/settings/tokens for classic tokens, or github.com/settings/personal-access-tokens for fine-grained ones. Delete or revoke the token and it stops working immediately. Tokens issued by a GitHub App or OAuth app are managed from Settings → Applications instead: revoke the authorization there.

How LeakWatch detects it

LeakWatch recognizes the ghp_, gho_, ghu_, ghs_ and ghr_ prefixes under the rule “GitHub Token”, and github_pat_ under the rule “GitHub Fine Grained PAT”. For the classic family, LeakWatch can check whether a detected token is still active with a read-only request that returns the account the token belongs to. It does not read your repositories or change anything. Fine-grained github_pat_ tokens are detected but not checked live: LeakWatch can tell you the token is exposed, not whether it still works, so assume it does until you have revoked it.

LeakWatch can check whether a detected key is still active with a read-only request to GitHub. It never reads your data or spends your credits.

FAQ

Does a fine-grained token make a leak harmless?

No. It narrows the damage to the repositories and permissions you selected, which is a real improvement, but a token with write access to one production repository can still push code that your servers will deploy. Revoke it regardless.

GitHub emailed me that it revoked my token. Am I done?

Not quite. The token is dead, but whoever copied it before that may already have used it. Check the security log and the repositories it could reach, and rotate any secret stored in them.

Can a GitHub token be used to reach other services?

Indirectly, yes. Repositories often hold cloud keys, registry credentials and CI secrets, and workflow permissions can expose more. That is why step 5 matters more than it looks.

Get alerted next time a secret leaks — create a free account

LeakWatch is not affiliated with GitHub.