This repository was archived by the owner on Jul 16, 2026. It is now read-only.
fix(sandbox): refresh GitHub installation token for the sandbox lifetime - #1
Merged
Merged
Conversation
GitHub App installation tokens expire after 60 minutes (fixed by GitHub, not extendable). The entrypoint minted one at boot only, so warm-pool sandboxes claimed >1h after creation — and any session outliving the hour — served dead tokens: every GitHub call 401'd (nixmac#514, voy#1130, travel-frens#246, 2026-07-09/10). - background loop re-mints on an interval (default 50 min: hourly cadence with margin so a live token always exists) and atomically rewrites the token file + git credential store for the sandbox's whole life - no GITHUB_TOKEN/GH_TOKEN env export on the mint path: env freezes into the exec'd harness and cannot be refreshed; a /usr/local/bin/gh wrapper re-reads the token file per invocation instead, and the env vars are unset so no stale/stub value can shadow the fresh sources - legacy env-token deployments (no App creds) keep the old behavior; the tail auth block pins /usr/bin/gh to bypass the wrapper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
GitHub App installation tokens expire after 60 minutes — fixed by GitHub, not extendable (a 4-hour token is not a thing GitHub offers). The sandbox entrypoint minted one once at boot; warm-pool sandboxes claimed >1 h after creation (and sessions outliving the hour) served dead tokens — every GitHub call 401'd. Verified across 16 auto_review jobs on 2026-07-09/10: all credential failures were sandboxes >60 min old at claim (nixmac#514 at 74 min, voy#1130 at 211 min, travel-frens#246 at 60 min); everything claimed fresh posted reviews fine.
Change
GITHUB_TOKEN_REFRESH_SECONDS, default 3000 s = 50 min — hourly cadence with margin so a live token always exists): re-mints and atomically rewrites the token file (~/.centaur/github-token, 0600) + git credential store, for the sandbox's whole life (idle-warm and claimed). Fail-soft: a failed re-mint keeps the previous token and retries in 300 s.GITHUB_TOKEN/GH_TOKENfreeze into the exec'd harness at boot and go stale where files can be refreshed — andghprefers env over everything. A/usr/local/bin/ghwrapper (shadows apt's/usr/bin/gh) re-reads the token file per invocation; both env vars are unset so no stale/stub value can shadow the fresh sources.gitreads the refreshed credential store.GITHUB_TOKENenv with no App creds keep the old behavior (unset is scoped to the mint path; wrapper is a passthrough without the token file; tail auth block pins/usr/bin/gh).Verification
Functional smoke (stubbed minter, real functions extracted from the entrypoint): boot mint writes 0600 token file + x-access-token credentials ✓; refresh loop re-mints on interval and swaps both files atomically ✓; poisoned minter keeps last token (fail-soft) ✓; wrapper overrides stale env from the file and passes through without it ✓.
bash -n/sh -nclean.Deploy
After merge + image build: bump
sandbox.image.tagin gitopsapps/centaur.yaml. Warm-pool pods pick the fix up on natural recycle (or delete the current warm pod — its token is already hours dead).