Your automation receives a secret, stores it, and then sends it to GitHub to read a repository. It was working yesterday, but a longer value is now truncated in the process. The permissions may be correct and the request can still fail. The end of the deployment of the new GitHub Apps installation tokens, announced on October 2, 2026, invites you to follow this secret throughout its journey.
Identify the relevant secret before looking everywhere
A GitHub App is an application to which you grant permissions on a set of repositories. Its installation has its own access context. The installation token is used for calls made in this context; it is different from a user's secret and the application's private key.
The GitHub documentation separates the application's authentication from the generation of a token for its installation. Before your audit, therefore, find the component that actually obtains the latter. A configuration simply bearing the name "GitHub token" is not enough to identify its family. Installation token documentation.
On October 2, GitHub announced the end of the deployment that began on April 27: the new installation tokens use a stateless format by default. They retain the prefix ghs_ and are about 520 characters, compared to 40 previously. The permissions, repository scope, one-hour expiration, and the endpoint remain unchanged. The temporary header X-GitHub-Stateless-S2S-Token will be deprecated on November 30, 2026. End of deployment announcement.
Stateless describes here the new format of the provider. You do not need to understand its inner workings to correctly transmit the secret. The value must remain opaque: your application carries it, but does not build its access rules by decoding what it thinks it recognizes. The published magnitude is not a new exact length to be enforced in a form.
Draw the actual route, from the supplier to the request
Our fictional example is an internal tool that checks the status of repositories. A service gets the token, a storage keeps it briefly, a worker process loads it, and an HTTP client sends it. An administration interface and an error collection can also handle it. Each of these steps can retain an old assumption.
Start with the names of variables, properties, and parameters that carry the value. Then look for constraints on their length and applied transformations: string slicing, character removal, encoding, or copying to a different field. A constraint can come from the code, a database schema, or an external component.
A column that is too short can cause an explicit error, but some paths may truncate silently. An interface field may reject input even before the network call. A log mask may recognize only the old secret and let part of the new one appear. So do not reduce the audit to the line that builds the authentication header.
| Component to be examined | Useful question | Expected proof |
|---|---|---|
| Obtaining service | Is the answer copied entirely? | Equality on a dummy value |
| Storage | Are the capacity and the controls suitable? | Read after writing without loss |
| Loading | Is the value changed in transit? | Comparison before and after passage |
| Network client | Does the header contain the correct value? | Capture in a simulated transport |
| Logs and errors | Does part of the secret appear? | Negative search in the outputs |
This grid is a Partitech proposal. Add one manager per line, because a successful test on the application code does not necessarily validate the proxy or the storage tool managed by another team.
Test a property, rather than an example of a format
The property being sought is simple: the value that goes in must be identical to the one that reaches the intended transport. A test string does not need to resemble a real secret. Choose an explicit prefix, for example FAUX_SECRET_TEST_, and various sizes, including one exceeding the announced order of magnitude. These values should never allow authentication.
You can include a short string, a longer one, and a value containing the characters your component accepts according to its contract. The sizes are local test parameters, not an estimate of future GitHub tokens. Maintain reasonable limits against abusive entries; only avoid constraints arising from an old format without technical justification.
Pseudocode of the proposed control, not executed here:
pour chaque valeur factice du jeu de test
écrire dans le stockage de test
relire par le chemin de chargement réel
envoyer au client HTTP simulé
vérifier l'égalité avec la valeur de départ
provoquer une erreur de transport simulée
vérifier l'absence de la valeur dans toutes les sorties
Add a case that deliberately exceeds the defined capacity of your component. The error must be clear and must neither truncate and then continue, nor display the received content. This test checks the quality of the rejection; it does not ask you to accept strings of infinite size.
For masking, look for the complete secret but also the recognizable segments that might be exposed. A rule that hides the beginning and shows the end is still a leak. Inspect the error response, the console, the structured logs, and any diagnostic attachments. Do this with dummy values, so that the investigation itself does not become an exposure.
Correct the faulty border without expanding rights
If the storage truncates, correct its capacity according to your application's conventions. If a regular expression requires exactly the old length, replace this assumption with a check consistent with actual usage. If a diagnostic tool recognizes only an old pattern, prefer removing the secret property from the collection rather than trying to guess all its future forms.
A formatting error does not justify adding permissions to the application. In our fictional tool, reading repositories remains reading repositories, even after correcting the storage. Check separately the permissions that are actually necessary; do not confuse a local denial with a remote authorization denial.
When a schema change is necessary, prepare it with the existing migration mechanism. Check the deployment order between the database and the code, old instances still active, and how they read the new data. A correctly widened write can still be misread by an instance that retains the old validation.
Avoid keeping more secrets to facilitate comparison. Your proof can record 'equality verified' and the name of the test scenario, without keeping the value. Temporary storage must preserve its expiration and access controls. The work focuses on faithful transport, not on multiplying copies.
Prepare for November 30 and monitoring
The May 15 announcement featured a temporary header allowing the selection of generation behavior during the transition. It remains a historical context, distinct from the end of the rollout announced in October. Announcement of the transition header.
List the components that still use this header. Assign the removal to a delivery version, with a responsible person and a compatibility test. The deadline of November 30 announced by GitHub must appear in your monitoring: a transition option is not a permanent rollback mechanism.
After local tests, an authorized check in a GitHub test environment can verify token retrieval and use, with the minimal necessary rights. It must keep secrets out of the captures. Distinguish in your report what the simulated transport proved from what this real call confirmed.
For monitoring, track errors by component and by stage: retrieval, storage, loading, query. Compare trends before and after delivery, without associating an incident with a format just because it appears on the same date. A refusal response can have multiple causes; your inventory allows you to test the correct hypothesis.
Choose a rollback that remains compatible
A rollback to an older version that truncates the new tokens would reintroduce the problem. Therefore, prepare a backup version that preserves the compatibility fix, or a plan to roll back the functional change that does not restore the old constraint. Document this point before launching the delivery.
The task can be considered qualified when the actual passages have a person in charge, the dummy tests fully preserve the value, the errors remain without secrecy, and the removal of the temporary header is planned. No test performed on a Partitech integration is claimed in this article.
For your next technical review, choose a single installation token path and apply the end-to-end framework. You will obtain a concrete scope of correction, instead of a general rewriting of authentication. Useful robustness depends on the fidelity of transport and the discretion of diagnostics, regardless of the current form of the secret.
Sources and verification date
Open sources on October 6, 2026: end of deployment, temporary header of May and GitHub Apps documentation. The described tests constitute a proposed protocol, without functional secrets or fabricated results.