Context
src/lib/github.ts mints runner registration and removal tokens using GITHUB_PAT exclusively. SECURITY.md already calls this out:
Runner registration currently uses GITHUB_PAT to mint short-lived runner registration and removal tokens. Treat that PAT as fleet-wide infrastructure auth... prefer narrowly scoped/fine-grained credentials where GitHub supports the required runner APIs.
A GitHub App installation token, scoped to the org and limited to Self-hosted runners: read & write, is the narrowest credential GitHub offers for this surface and avoids tying fleet auth to an individual user identity.
Scope
- Add an App-auth code path to
src/lib/github.ts:
- Read
GITHUB_APP_ID, GITHUB_APP_INSTALLATION_ID, and GITHUB_APP_PRIVATE_KEY (PEM, possibly base64-encoded) from env.
- Mint an installation token via JWT and cache it until ~5 minutes before expiry.
- Use the installation token for runner registration / removal / queue queries everywhere a PAT is currently used.
- Keep
GITHUB_PAT as a supported fallback so existing operators are not broken; pick App auth when App env vars are set, PAT otherwise.
- Update
.env.example, docs/bootstrap/, and SECURITY.md to describe the App-auth path and the minimum permissions needed.
- Extend
pnpm doctor / validate-github to recognize the App-auth config and verify the installation can mint a registration token end-to-end.
- Add unit tests covering: JWT signing path, token caching/refresh, fallback to PAT, and doctor surfacing of misconfigured App creds.
Acceptance Criteria
- An operator can deploy the fleet with only
GITHUB_APP_* env vars (no PAT) and complete install-synology-project, install-linux-docker-project, install-windows-project, and install-lume-project flows.
pnpm doctor reports App-auth status (installation ID, expiry of last minted token, accessible APIs).
SECURITY.md recommends App auth as the default and reframes PAT as the fallback.
- Existing PAT-only deployments continue to work unchanged.
Context
src/lib/github.tsmints runner registration and removal tokens usingGITHUB_PATexclusively.SECURITY.mdalready calls this out:A GitHub App installation token, scoped to the org and limited to
Self-hosted runners: read & write, is the narrowest credential GitHub offers for this surface and avoids tying fleet auth to an individual user identity.Scope
src/lib/github.ts:GITHUB_APP_ID,GITHUB_APP_INSTALLATION_ID, andGITHUB_APP_PRIVATE_KEY(PEM, possibly base64-encoded) from env.GITHUB_PATas a supported fallback so existing operators are not broken; pick App auth when App env vars are set, PAT otherwise..env.example,docs/bootstrap/, andSECURITY.mdto describe the App-auth path and the minimum permissions needed.pnpm doctor/validate-githubto recognize the App-auth config and verify the installation can mint a registration token end-to-end.Acceptance Criteria
GITHUB_APP_*env vars (no PAT) and completeinstall-synology-project,install-linux-docker-project,install-windows-project, andinstall-lume-projectflows.pnpm doctorreports App-auth status (installation ID, expiry of last minted token, accessible APIs).SECURITY.mdrecommends App auth as the default and reframes PAT as the fallback.