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.
| Prefix | Token | Typical use |
|---|---|---|
ghp_ | Personal access token (classic) | Broad personal API access. GitHub prefers fine-grained tokens. |
github_pat_ | Fine-grained personal access token | Personal API use with narrower scoping. |
gho_ | OAuth access token | Access through an OAuth app. |
ghu_ | User access token for a GitHub App | Acting for a user through an app. |
ghs_ | Installation access token for a GitHub App | Acting as the app installation, for example in an organization. |
ghr_ | Refresh token for a GitHub App | Refreshing 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.
- 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.
- 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
- 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_TOKENcannot cross repositories. Those are the jobs to move to a GitHub App.
What to do now
- 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.
- 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.
- 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. - Use the October additions for the jobs that used to need
repoor repository administration rights:repository_creation:writecreates repositories withoutrepository_administration:write, which also allows deletion and transfer.installation_repositories:writeadds or removes repositories on installations, and those endpoints now accept GitHub Apps and fine-grained tokens instead of the coarsereposcope.
- 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.
- 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.
- 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.