Safeguard
Supply Chain Security•

GitHub App Tokens Are Now About 520 Characters. What Breaks?

GitHub finished rolling out stateless App installation tokens on 2 October 2026. They keep the ghs_ prefix but grow from 40 to about 520 characters.

Safeguard Security Team
5 min read

On 2 October 2026 GitHub announced that its staged rollout of stateless GitHub App installation tokens, which began on 27 April, is complete. New installation tokens now use a ghs_APPID_JWT format by default. They still start with ghs_, but they are roughly 520 characters long instead of 40.

Permissions, repository scoping and the one-hour expiry are unchanged. What changes is every system that quietly assumed a token is short.

What's affected

Anything that mints, stores, forwards or redacts GitHub App installation tokens:

  • CI systems and bots that authenticate as a GitHub App, including tokens minted inside workflows by actions that exchange an App private key for an installation token.
  • Internal platforms that cache installation tokens in a database or secret store.
  • Proxies, API gateways and service meshes sitting between your services and api.github.com.
  • Secret scanners, DLP rules and log redaction filters that match GitHub tokens by pattern.

GitHub's changelog lists the specific things to check: validation that expects exactly 40 characters or the legacy pattern, database columns or secret stores with a small fixed maximum length, proxies or middleware that truncate or reject long Authorization headers, and logging or redaction rules that only match the legacy pattern.

There is also a deadline. During the rollout GitHub offered a temporary X-GitHub-Stateless-S2S-Token request header to opt in or out per request. That header is deprecated as of 30 November 2026. After that date GitHub ignores it and eligible apps always receive stateless tokens. Tokens minted before the change keep working until they expire.

How to check if you're exposed

Search your code and config for hard-coded token shapes:

# Length or regex assumptions about ghs_ tokens
grep -rnE "ghs_\[A-Za-z0-9\]\{36\}|ghs_.\{36\}|len\(.*token.*\) *== *40|length *=== *40" .

# Uses of the temporary opt-in header
grep -rn "X-GitHub-Stateless-S2S-Token" .

Check storage schemas for short columns:

SELECT table_name, column_name, character_maximum_length
FROM information_schema.columns
WHERE column_name ILIKE '%token%'
  AND character_maximum_length IS NOT NULL
  AND character_maximum_length < 1024;

Check your log redaction. Mint a token in a test environment, log a request that includes it, and confirm the whole value is masked, not just the first 40 characters. A redaction rule written for the old format may now mask the start of the token and print the rest.

Finally, check proxy header limits. Most proxies allow headers far longer than 520 bytes, but custom middleware and some WAF rules cap individual header sizes.

What to do now

  1. Treat installation tokens as opaque strings. Remove length checks and strict regexes from validation code. If you must validate, check the ghs_ prefix only.
  2. Widen storage. Use unbounded text columns, or at least a limit well above 520, for any token field.
  3. Update redaction and secret scanning rules so they match ghs_ followed by any long run of token characters, not exactly 36.
  4. Remove X-GitHub-Stateless-S2S-Token before 30 November 2026. If you used it to opt out while you fixed things, those fixes now have a deadline.
  5. Test the whole path. Mint a token, store it, retrieve it, use it through your proxy, and check the logs. One run end to end catches most problems.
  6. Don't log tokens at all. A longer token is a good reason to audit why tokens reach logs in the first place.

Why it matters

Token formats are an interface, even when vendors say they aren't. Teams write length checks to catch truncation bugs, regexes to find leaked secrets, and fixed-width columns because they looked at a sample. Each of those is a reasonable choice that becomes a break when the format changes.

The security angle is redaction. A redaction rule that matches exactly 40 characters will either miss the new token entirely or mask only part of it. A partly masked 520-character token is still a leaked token. GitHub's own guidance calls out logging and redaction rules, which is the item most likely to fail silently.

GitHub gave notice in its changelog and ran a staged rollout from April to October. The teams that will feel this are those who don't read platform changelogs, which is a good reason to make reading them someone's job.

Try it yourself

Run the grep commands above on one repository that talks to GitHub as an App. Then check your secret scanner's GitHub token rule against a sample 520-character ghs_ string from a test App. The demo below shows how secret scanning flags tokens committed to code, a useful place to confirm your patterns still match.

Click through it at your own pace, or open it full screen.

Quick check

Do stateless tokens change what a GitHub App can access?

No. GitHub says permissions, repository scoping, the one-hour expiration and the installation access token endpoint are unchanged. Only the format and length change.

What happens on 30 November 2026?

The temporary X-GitHub-Stateless-S2S-Token header is deprecated. GitHub ignores it from then on, and eligible apps always receive stateless tokens.

Do I need to revoke tokens minted before the change?

No. Tokens minted before the change keep working until they expire, which is at most one hour.

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.