Skip to content

GitHub App installation tokens are now 520-character JWTs

GitHub finished moving App installation tokens to a stateless format on October 2. They now run about 520 characters, up from 40, and old checks may break.

By Tech AI Wire Team

3 min read

XLinkedIn
Screenshot of the GitHub Changelog post 'Stateless GitHub App installation tokens rolled out', dated October 2, 2026, above GitHub's blue Octocat artwork.

By the numbers

characters in the old installation token
40
characters in the new stateless token
~520
when the opt-out header is deprecated
Nov 30

GitHub has finished switching every newly created GitHub App installation token to a new "stateless" format, the company said in its changelog on October 2, 2026. The tokens still start with ghs_, but they are now about 520 characters long instead of 40. Any code that assumed the old length, such as a validation pattern or a database column, can now reject or cut off a working token.

What changed

An installation token is the short-lived password a GitHub App uses to act on the repositories it is installed on. GitHub started a staged rollout of the new format on April 27, 2026. The October 2 changelog says that rollout is complete, so the new format is now the default.

The new token is a JWT, short for JSON Web Token: a signed string that carries information inside it. According to GitHub's May changelog, you can tell the two formats apart by counting dots. A stateless token contains two dots, while the old opaque token contains none.

Old formatNew format
Prefixghs_ghs_
Length40 characters, fixedabout 520 characters, can vary
Dots in the token02
Lifetime1 hour1 hour, unchanged

Permissions, repository scoping and the one-hour expiry stay the same, GitHub says. Only the shape of the string changed.

What the token carries

MongoDB's Kingfisher project, a scanner that hunts for leaked secrets, described the format in an issue filed on April 26. It writes the pattern as ghs_APPID_JWT. The JWT part holds details such as the target installation and the app, plus basic validation data, according to the issue.

That JWT is signed by GitHub's own internal issuer. The Kingfisher issue says client apps should not try to validate it. To your code, the token should stay an opaque string: something you store and send, never parse.

Kingfisher also flagged that its own detection rule for these tokens would need an update once the rollout finished. Secret scanners that match the old 40-character shape are one of the places this change shows up first.

The override header and its deadline

In May, GitHub added a temporary header, X-GitHub-Stateless-S2S-Token, to the request that creates an installation token. Sending enabled returns a new-format token. Sending disabled returns an old-format token, even for apps already moved over. Leaving the header off follows the default.

That escape hatch is closing. The October 2 changelog says the header will be deprecated on November 30, 2026. After that date, teams that pinned the old format to buy time will lose that option.

GitHub's May changelog lists GitHub Enterprise Cloud and its data residency regions as covered. It also names Actions' GITHUB_TOKEN, the token workflows use, alongside server-to-server App tokens.

What this means for developers

Search your code for anything that treats these tokens as fixed-size. GitHub's guidance names four trouble spots: length checks, database column limits, header truncation and log patterns. Each one can fail quietly. A column that holds 40 or 255 characters will cut the token, and the API call will then fail with what looks like an auth error.

Fix validation patterns next. A pattern like ghs_[A-Za-z0-9]{36} rejects the new token, because the token is longer and contains dots. GitHub's May changelog suggests ghs_[A-Za-z0-9.\-_]{36,}, which matches both formats. Check your own pattern against a made-up sample of each shape in a regex tester, never a live token.

Make sure storage holds at least 520 characters, GitHub says. That includes caches, secret stores and environment variables with size limits. If you redact secrets in logs, test that your redaction still catches the longer token. Otherwise part of a live credential could end up in plain text.

If you set the override header to disabled this spring, you have until November 30 to remove it. Test with enabled first, then delete the header.

Sources

  1. Stateless GitHub App installation tokens rolled out - GitHub Changelog
  2. GitHub App installation tokens: Per-request override header - GitHub Changelog
  3. Upcoming changes to GitHub App installation tokens format - MongoDB Kingfisher on GitHub
  4. Generating an installation access token for a GitHub App - GitHub Docs
securityapiauthentication

Related articles

The daily brief

Three to five stories a day, and what each one means for the people who build software. Free, no spam.