GitHub App Installation Tokens Grew to 520 Characters. Audit Every Handoff
GitHub's stateless App token rollout is complete. Find fixed-length assumptions in databases, proxies, logs and middleware before the Nov 30 test-header cutoff.
On this page
An integration can keep working for months and then fail because a credential grew. GitHub has completed its staged rollout of a stateless format for newly issued GitHub App installation tokens. The interface still looks like “a token in an Authorization header,” but the value is now roughly thirteen times longer. Teams should trace the token through every system that stores, forwards, validates or logs it.

What changed, and what did not
GitHub says new installation tokens remain prefixed with ghs_, while their typical length changes from 40 characters to about 520. GitHub describes the new format as improving token issuance performance and API reliability. It says the repository scope, permission set, one-hour lifetime and REST endpoint are unchanged. Previously minted tokens continue to work until they expire. [1]
That boundary matters. This is a token representation change, not a permission expansion. An installation token can still be limited to repositories and permissions already granted to its GitHub App installation, and GitHub documents a one-hour expiry. The new string should still be treated as a secret bearer credential. It should not be parsed for authorization logic simply because its internal representation changed. [2] [4]
GitHub’s temporary request header, X-GitHub-Stateless-S2S-Token, was offered during the staged rollout to let app owners test the format on demand. GitHub says it will stop respecting that header on November 30, 2026; eligible apps will receive stateless tokens by default. Remove the compatibility switch after you have exercised both formats. [1]
The likely failure is between GitHub and your code
GitHub lists several places to inspect: length validation, database columns, secret stores, environment variables, proxies, gateways, middleware and redaction rules. These are common seams because teams often introduce a “convenient” constraint far from the code that first receives the token. A schema might use a 64-character field. A regular expression may accept only forty characters. A gateway may impose a small header limit. A log scrubber may redact values that match the old pattern and accidentally print the longer form. [1]
Follow one token path in a non-production test installation. Generate a token using GitHub’s documented flow, pass it through the same request stack as production, and confirm that the receiving service uses it successfully. Inspect only whether the value was accepted, stored and redacted; do not print or paste the token into logs, a ticket or a shell transcript. If an SDK handles authentication for you, verify the SDK version and its documented behavior rather than adding a second token parser. GitHub notes that Octokit can generate and renew installation tokens automatically. [2]
Then search source and configuration for assumptions such as length === 40, fixed-size character fields, token-shaped regular expressions, and request-header limits. Check both write and read paths: a field can accept the longer value but truncate it when returned by a database driver, copied into a queue, or exported to an audit event. Include observability. Secret filtering should redact credential fields based on their context and label, not rely solely on the old token’s length or exact encoding.
Keep the security model opaque
“Stateless” does not mean “safe to decode in your app.” The implementation should continue to send the token as an authorization credential and let GitHub enforce its validity, expiry and granted access. Do not use a prefix or internal token segment as proof of identity. Do not turn the value into a cache key that appears in URLs or metrics. Where a system needs correlation, log a separate request or installation identifier that is not itself an authenticator.
Also review scope independently of string length. GitHub’s token creation endpoint supports repository and permission restrictions within what the app has already been granted. If a service does not need every repository available to an installation, request a narrower set. A format migration is a good moment to confirm that least privilege still holds, but it is not evidence that the app’s existing permissions have changed. [2] [4]
Related reading: how to pin GitHub Actions dependencies and reduce workflow drift and a practical look at GitHub license-compliance rulesets.
A short migration plan
- Generate both formats in a test installation while GitHub’s temporary header is still supported.
- Exercise issuance, persistence, queueing, proxying, API calls, expiry and rotation without exposing credentials in traces.
- Replace fixed-length checks with a boundary appropriate to the transport and storage layer, while treating the token as opaque.
- Confirm that logging and tracing redact the whole secret in both formats.
- Remove the temporary header before November 30 and retain a regression case for an unusually long credential.
The rollout is already complete, so waiting for an application to fail is not a useful test strategy. If an integration already handles arbitrary bearer-token strings, it may require no code change. The evidence to gather is narrower: the full authentication path accepts the current format without truncation, and the credential never leaks through persistence or observability.
Frequently asked questions
What changed about GitHub App installation tokens?
GitHub completed the rollout of a stateless format for newly minted installation tokens. They still begin with ghs_ but are now about 520 characters instead of 40; their permissions, repository scope, one-hour expiry and token-creation endpoint remain unchanged.
Will every GitHub App integration break?
No. Integrations that treat tokens as opaque strings and pass them through ordinary authorization headers may need no change. Fixed-length validation, short database columns, header limits and legacy-only redaction patterns are likely failure points.
When does the temporary test header stop working?
GitHub says it will deprecate X-GitHub-Stateless-S2S-Token on November 30, 2026. Eligible apps will receive stateless tokens by default after the rollout, so teams should remove the temporary header after testing both formats.



/* Comments */
Comments are offline right now — we reconnect automatically, nothing is lost.