A token passes through a library, a secret store, a proxy and log-redaction rules. Each layer may have its own idea of the expected length. The provider changes the format, and our integration discovers that a “string” had a hidden contract after all.
What GitHub confirmed
Event date: 2 October 2026. GitHub announced completion of the stateless GitHub App installation-token rollout. New tokens retain the ghs_ prefix but are approximately 520 characters rather than 40. Permissions, repository scope and one-hour expiry are unchanged. The temporary X-GitHub-Stateless-S2S-Token header will be deprecated on 30 November 2026.
The source reports a product change, not an outage in a particular integration. “Approximately 520” is not a new fixed length to hardcode into a validator.
What this means for architecture
ArchitectMentor interpretation: an integration should pass the token without depending on its internal structure. It is a credential for the provider’s API, not our data model. Merely forwarding it requires neither decoding its parts nor implementing our own signature validation. The server’s response determines acceptance; a local length check cannot replace that.
This does not remove the need for limits. Header and storage limits still matter. Size them for supported credentials, document them and test them instead of inheriting them from an old example. A larger token is not a reason to grant broader permissions either.
Check four places
| Layer | Possible failure | Verification |
|---|---|---|
| Validation and libraries | An exact 40-character check or a legacy-format pattern. | Pass a longer value unchanged; then test a newly issued token through the API. |
| Secret store and database | Silent truncation, an undersized column or a field limit. | Write and read a synthetic string of representative length; compare values in memory without printing them. |
| Proxy and gateway | A rejected or truncated Authorization header. | Use the actual request route and check responses at each stage. |
| Logs and telemetry | Redaction recognises only the legacy pattern. | A synthetic marker resembling the new format must not appear in any collected log. |
Two tests answer different questions
Fictional educational example: a documentation worker obtains a token, stores it and calls the API through a corporate proxy. A long synthetic-string test can show that storage and transport do not truncate the value. It cannot prove that GitHub accepts the credential.
Run a second test on a test installation with minimal scope and a freshly issued token: perform an allowed read operation through the same route. If it fails, distinguish format handling from permissions, expiry and installation configuration. Do not print the full header to “see what was really sent”. That is a convenient way to create another problem.
Also check acquisition of a fresh token after the previous one expires. One successful request using a cached value does not establish that renewal works.
Decision and boundaries
Remove dependencies on the old length first, then verify storage, transport, redaction and renewal. Only after checking integrations should you remove the temporary header before its retirement date. If a token may have reached logs, restrict access, revoke the exposed credential using the provider’s procedure and investigate the exposure scope.
This announcement concerns GitHub App installation tokens in GitHub Enterprise Cloud and Data Residency environments; the earlier scope documentation excludes GitHub Enterprise Server. It does not establish a format change for every PAT, OAuth token or locally issued JWT. It also provides no basis for claiming an outage at any organisation.
Learn: how to verify API contract compatibility →
Discuss this article
Share a constructive observation or an anonymised example. Comments are checked by AI before publication. Uncertain cases go to the moderator.