GitHub News

GitHub App tokens are now about 520 characters long. Check your agent's plumbing before November 30

Installation tokens switched from 40 characters to a JWT-based format, and a temporary opt-in header has a removal deadline.

GitHub finished rolling out stateless installation tokens on October 2. Every new installation token for a GitHub App now looks like ghs_APPID_JWT and runs to roughly 520 characters, up from 40, according to the GitHub changelog . If you run a bot, a review agent or any automation that authenticates as an app, something in your pipeline may have an opinion about that length.

GitHub says permissions, repository scoping, the one-hour expiry and the REST endpoint that issues the token are all unchanged. What changed is how the token is made and checked: GitHub says the new format makes issuance and validation faster and improves API reliability. The staged rollout started April 27.

Why agent setups are the likely casualties

Apps that act on repositories (review bots, PR agents, anything minting a token per job) tend to pass that token through several hands. A secrets store, an environment variable, a database row, a proxy, a log scrubber. Each is a place where “a token is 40 characters” may be baked in.

GitHub lists four things to audit:

  • Code that validates tokens against a hardcoded 40-character length.
  • Database columns too short to hold about 520 characters.
  • Proxies or middleware that truncate long headers.
  • Secret redaction rules that only match the legacy pattern.

The last one deserves the most attention. A scrubber that doesn’t recognise the new shape won’t fail loudly. It will just let a live token into your CI logs or an agent transcript, where it stays valid for up to an hour.

The deadline

During the rollout, GitHub offered a temporary request header, X-GitHub-Stateless-S2S-Token, to opt in early. It has to be gone from production code by November 30, 2026. If you added it to test, remove it. If you inherited an app and don’t know whether it’s set, search the codebase for the header name.

A ten-minute check

Mint a token from your app and run it through every stage of your own pipeline. A quick look at what you’re dealing with:

# TOKEN holds a freshly minted installation token
printf '%s' "$TOKEN" | wc -c

Expect roughly 520. Then confirm it survives storage and transport intact: write it to wherever you keep tokens, read it back, compare. Then send a deliberately fake token of the same shape through your log redaction and check that it comes out masked.

None of this is hard, and most apps will pass untouched. But the failure mode of the ones that don’t is a truncated credential or a leaked one, and it’s cheaper to find out this week than after the header goes away.