Safeguard
Application Security•

GitHub Token Types and How to Move Off Classic PATs in 2026

GitHub's 13 October 2026 app changes remove two reasons to keep a classic PAT. A field guide to each token prefix, which to use, and the org policy that retires classic tokens.

Safeguard Security Team
5 min read

On 13 October 2026 GitHub shipped a set of GitHub App improvements and said plainly that the aim is to help developers move off classic personal access tokens. Two new fine-grained permissions, repository_creation:write and installation_repositories:write, mean the automation that used to need a broad repo token can now run with much less.

This is a good moment to sort out which GitHub token is which, because most teams still have a classic token (ghp_) in a CI secret that nobody remembers creating.

What's affected

GitHub documents six token formats. The prefix tells you what a leaked string can do.

PrefixTokenTypical use
ghp_Personal access token (classic)Broad personal API access. GitHub prefers fine-grained tokens.
github_pat_Fine-grained personal access tokenPersonal API use with narrower scoping.
gho_OAuth access tokenAccess through an OAuth app.
ghu_User access token for a GitHub AppActing for a user through an app.
ghs_Installation access token for a GitHub AppActing as the app installation, for example in an organization.
ghr_Refresh token for a GitHub AppRefreshing user access tokens.

GitHub's guidance on choosing is short. For personal use, a fine-grained token. For an organization or another user, a GitHub App. For GitHub Actions, the built-in GITHUB_TOKEN with the permissions key, which only reaches the workflow's own repository. OAuth apps are a fallback, since GitHub recommends a GitHub App instead.

Two more facts matter for audits. Classic tokens are not subject to the organization approval policy: unless an org or enterprise restricts them, any classic token can reach org resources without approval. And both token types are enabled by default.

How to check if you're exposed

Look at your own estate in three places.

  1. Organization settings. Open the org, then Settings, then Personal access tokens. The Fine-grained tokens tab and the Tokens (classic) tab each hold a policy. Note whether classic tokens are currently allowed.
  2. Code and CI. Search repositories and CI variables for the prefixes above. A ghp_ hit in a pipeline is your migration list.
git grep -nE 'ghp_[A-Za-z0-9]{20,}|github_pat_[A-Za-z0-9_]{20,}' $(git rev-list --all | head -50) | head
  1. Workflows that reach other repositories. A job that checks out a second repository or pushes to it is usually where a PAT got introduced, because GITHUB_TOKEN cannot cross repositories. Those are the jobs to move to a GitHub App.

What to do now

  1. Put an owner of each classic token on the hook. Ask who created it, which repositories it truly needs, and what breaks if it is revoked.
  2. Replace personal tokens used for scripts with fine-grained ones scoped to named repositories and the minimum permission set. Give them an expiry you will actually review.
  3. Replace shared automation tokens with a GitHub App, installed only on the repositories it needs. Installation tokens (ghs_) act as the app installation, not as a person, so they do not break when someone leaves.
  4. Use the October additions for the jobs that used to need repo or repository administration rights:
    • repository_creation:write creates repositories without repository_administration:write, which also allows deletion and transfer.
    • installation_repositories:write adds or removes repositories on installations, and those endpoints now accept GitHub Apps and fine-grained tokens instead of the coarse repo scope.
  5. Know the approval limits. Repository admins can now add their repositories to an app an owner has already approved at the org level, without owner approval. Org-level permissions, repository administration and repository creation still need owner approval, and owners can block the feature by restricting installation to owners.
  6. When no classic token is left, restrict them. On the Tokens (classic) tab choose the option to restrict personal access tokens (classic) from accessing your organizations. Keep fine-grained tokens on "Require administrator approval", which is the default for that policy.
  7. Plan for the one-time change in ghs_ tokens. GitHub has begun a staged rollout of a stateless installation token format, ghs_APPID_JWT. Code that assumes a 40 character token may fail.

Restricting a token type does not stop it reading the organization's public resources. GitHub says that stays available whatever the policy.

Why it matters

A classic token is a password with a scope list. It is tied to a person, it often outlives the project it was made for, and it works anywhere that person can. When it leaks, the blast radius is whatever that person could reach, not whatever the script needed.

Fine-grained tokens and apps shrink that radius, but only if someone writes down the permissions. The October changelog is useful because it removes the excuse. The job that creates a repository for each new customer no longer needs an admin's token.

The policy step is the one that sticks. Without the restriction setting, a classic token can be created again next month by someone in a hurry.

Quick check

A token starts with ghs_. What is it?

An installation access token for a GitHub App. It acts as the app installation, not as a person.

Does the organization approval policy apply to classic tokens?

No. Approval applies to fine-grained tokens. Classic tokens reach org resources without approval unless the organization or enterprise restricts them.

Which token should a workflow use for its own repository?

The built-in GITHUB_TOKEN, with a permissions block that grants only what the job needs.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.