GitHub tracker: support renewable GitHub App installation tokens via token file #128
blakedehaas
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Summary
While deploying Symphony as the orchestration layer for the autonomous software factory behind Simulated Singularity, I encountered a credential-lifecycle limitation in the GitHub Issues adapter. The deployment is reproducible in the open-source repository: https://github.com/blakedehaas/simulated-singularity
Symphony currently supports
tracker.provider.token/GITHUB_TOKEN, but long-running Symphony processes cannot transparently rotate that credential when using short-lived GitHub App installation tokens.I propose adding a
tracker.provider.token_fileoption that is reread on each GitHub API request. A controller-side credential broker could then atomically replace the file with a newly minted installation token without restarting Symphony and without exposing the GitHub App private key to Codex workers.Context
The software-factory architecture uses Symphony and Codex with strong separation of responsibilities:
For GitHub access, the controller uses a dedicated repository-scoped GitHub App rather than a personal access token.
The App is responsible for operations such as:
The design deliberately keeps the GitHub App private key outside Codex worker environments. Workers should only operate with tightly scoped permissions and should never require access to the App private key.
That architecture exposed the token-rotation problem described here.
Motivation
The deployment uses:
GitHub App installation tokens are intentionally short-lived.
The current static-token model therefore creates an operational mismatch: an installation token can expire while Symphony is still running.
Restarting Symphony periodically solely to rotate that credential is undesirable because it may disrupt orchestration state or long-running agent activity.
Passing the GitHub App private key into the Symphony/Codex worker environment would solve the refresh problem in the wrong place and weaken the security boundary.
A token-file abstraction allows the trust boundary to remain:
The credential broker can rotate
/runtime/github-tokenatomically.Symphony only receives the current short-lived credential.
Codex workers never need access to the App private key.
Proposed configuration
Environment-variable indirection could also be supported:
Existing
token/GITHUB_TOKENbehavior should remain unchanged for backward compatibility.Proposed behavior
For each GitHub API request:
token_filewhen configured.token/GITHUB_TOKENbehavior.Reading the file per request is intentional: an external credential broker can rotate the token atomically while Symphony remains alive.
Because scheduler polling and the injected
github_apitool both pass through the GitHub client, both paths can inherit token rotation without changes to worker behavior.Minimal implementation
In
elixir/lib/symphony_elixir/github/client.ex:Then resolve the GitHub credential using:
secret_environment_names/1can also includeGITHUB_TOKEN_FILEand any configured$VARreference fortoken_file, preserving Symphony's existing credential-isolation behavior for Codex children.Regression test
A focused test can prove that the value is actually reread rather than cached:
Security and operational benefits
This would:
WORKFLOW.md;Real-world reproduction
The complete autonomous workflow has been exercised successfully:
An end-to-end smoke test successfully created an issue-specific branch, committed a test artifact, validated it, pushed the branch, opened a pull request against the integration branch, posted a handoff comment, and removed its dispatch label when complete.
The remaining infrastructure problem is credential lifecycle: GitHub App installation tokens expire much sooner than Symphony itself is expected to run.
I currently have the
token_fileapproach implemented as a narrow downstream compatibility patch against Symphony v0.0.2, along with a token-rotation regression test. The preference is to remove that downstream patch once Symphony provides an upstream-supported mechanism.If maintainers prefer a different abstraction—for example a credential-provider callback, executable credential helper, first-class GitHub App configuration, or another renewable-secret interface—the underlying requirement is simply:
All reactions