Skip to content
OTFotf
All posts

Does anything still expect a 40-character GitHub token?

D
DaveAuthor
6 min read
Does anything still expect a 40-character GitHub token?

GitHub says the staged rollout of stateless GitHub App installation tokens, which began on April 27, 2026, is complete. Newly minted installation tokens still start with ghs_, but they are now about 520 characters long instead of 40. So the buyer question is concrete: which store, proxy, or redaction rule in your system still assumes a 40-character ghs_ token, and have you deleted the temporary stateless header before 30 Nov?

The facts below come from GitHub's changelog entry of 2 October 2026, re-read on 3 Oct. Advice that is ours rather than GitHub's is marked "our suggested practice" or "in our view", so you can tell the two apart.

What GitHub says changed

According to the changelog, all newly minted GitHub App installation tokens are now in the stateless ghs_APPID_JWT format by default. GitHub gives the reason as faster token issuance and validation, plus better reliability for the GitHub API.

Explicitly unchanged: token permissions, repository scoping, the one-hour expiration, and the installation access token REST API endpoint. Tokens minted before the change keep working until they expire.

That is a narrow change. Nothing about what a token may do moved. What moved is the size of the string you receive, and the one thing GitHub asks every integration to confirm: that it treats installation tokens as opaque strings.

Where GitHub tells you to look

GitHub's own checklist names these risks. Each is a place where a number chosen for the old size can quietly clip or leak a longer secret.

Validation and patterns written for 40 characters

The changelog warns about validation that requires tokens to be exactly 40 characters, and about patterns written for the legacy format. In our view, search for length constants and regular expressions that mention ghs_ and swap them for a check that only confirms the value is non-empty. If you keep a format check, ask whether it protects anything or only encodes an old size.

Columns, secret stores, and environment variables

GitHub lists database columns, secret stores, and environment variables with a fixed or small maximum length. A column declared for exactly 40 characters, or a round number just above it, is the classic case. A quick way to find the clipper: read the table definitions, the generated migrations, and any form field with a maxlength, then store a 520-character fixture and read it back. A shorter result means something is cutting the token. That is our advice, not GitHub's.

Proxies, gateways, and middleware

The changelog says proxies, gateways, or middleware may truncate or reject long Authorization headers. It does not give header-size numbers, so we will not invent any. We would list every hop between your app and GitHub, ask each owner for its header limit, and send one long test value through the real path. A truncating hop turns a valid credential into a failing one.

In the picture below, a glowing strip is pulled back out of a slot on a device. Run the same check on each hop: put a long value in, then look at what comes out the other end.

Two people at a bench pull a pale glowing strip out of a slot on a gray device.

Logging and redaction rules

GitHub's last item is logging and secret redaction rules that only match the legacy token pattern. In our reading, this is the one that leaks rather than fails. A rule that masks forty characters and stops leaves the rest of a longer credential in the log.

In our view you should mask the whole credential after the prefix instead of a fixed count, and test the rule with a long fixture. Error reporters and trace exports deserve the same treatment wherever a request header can be copied. For a broader pattern, our post on rotating production secrets with dual-key overlap has a section on never logging the value, and the structured log contract for agents covers keeping log shapes stable.

Same component. Web and mobile. One codebase.

The free, open-source SDK gives you components that work the same on web and mobile — one codebase. github.com/otf-kit/sdk

Get the free SDK

The temporary header and its 30 Nov date

GitHub introduced a temporary request header, X-GitHub-Stateless-S2S-Token, so that you could validate the new format on demand. It will be deprecated on November 30, 2026. After that date GitHub will no longer respect the header, and all eligible apps will always receive stateless tokens.

GitHub's instruction is plain: once you have validated your apps and workflows with both token formats, remove the header from your production code before November 30, 2026.

In our view, grep for the header name in application code, client libraries, test helpers, feature flags, and any proxy rules that add it, then delete each use now rather than on the deadline. If you only set it to test, removal should be a small change. If something else started depending on it, you want to learn that in October.

In the picture below, a notebook holds a green check and a grid board has one square circled. Treat the header removal the same way: one dated item, ticked off well before the circled day.

Two people at a desk, one holding a small black device beside an open laptop and the other writing in a yellow notebook, with a grid board behind them.

A five-step test order

This order is our suggested practice, not a GitHub procedure. Work outward from the call that requests a token:

  1. Request a token the way production does and record its length in a test, not in a log.
  2. Write it through the same function production uses, then read it back and compare.
  3. Send a request through the real proxy path and confirm GitHub accepts it.
  4. Trigger a handled failure that normally logs HTTP context and check that no part of the token appears.
  5. Search for the header name and for 40-character checks, and remove both.

Search more than the application repository. Column definitions live in migrations, header limits live in gateway configuration, and redaction rules often live in a shared logging module owned by another team.

Older short tokens may still be in circulation next to new long ones, so test with both a short and a long fixture.

Where Arcade fits, and where it does not

Arcade does not itself handle GitHub App tokens, so nothing in it fixes this audit. It is relevant only if you want a codebase to experiment on. The Arcade Games Showcase Kit is listed as a live $99 kit built on Expo and Hono (React Native), with editable source delivered into a repository you control and a CLAUDE.md in the repo. You can try the free Arcade demo before deciding. If a different shape fits better, the pricing page lists the SaaS Dashboard kit and the Fitness and Wellness kit as the other live options.

FAQ

Are the new tokens a different permission grant?

No. GitHub says token permissions, repository scoping, the one-hour expiration, and the installation access token REST API endpoint are unchanged. The token string is longer and stateless.

Do tokens minted before the change stop working?

No. GitHub says tokens minted before the change keep working until they expire.

Which format are the new tokens in?

GitHub says they still start with ghs_ and are about 520 characters long instead of 40. The changelog describes the format as ghs_APPID_JWT.

When must the temporary header be removed?

Before November 30, 2026. GitHub says it will be deprecated on that date and will no longer be respected.

Sources

githubgithub-appssecurity
OTF SDK + Kits

Buy once, own the code. Ship with the agent you already use.

  • Free, open-source SDK — same component, web and mobile
  • Paid kits include AI configs + 40+ tested prompts — your agent reads the whole project
  • $99/kit or $149 for everything. No subscription, no sandbox limit.
Need more than components?

Full-stack kits.
Pay once, own the code.

Auth, database, and payments already connected — so you ship product, not setup. Or take every kit in the Bundle.

Everything Bundle — $149See full pricing

Get the free AI configs pack

Pre-tuned AI configs for Cursor, Claude, and Lovable — drop them in and your AI tool instantly understands your project.

No spam. Unsubscribe any time.

Prefer the free SDK? Star it on GitHub →