From 674933764bd105420e6f90f4245869890cd8f803 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 24 Aug 2026 11:26:13 -0700 Subject: [PATCH] fix(drift-audit): mint the publish-bot App token so the audit can read the org The audit ran on GITHUB_TOKEN, which is scoped to displayxr-runtime alone. That silently degraded every cross-repo READ against a private sibling -- displayxr-shell-pvt resolved to "could not fetch ... skipped" notes rather than findings, so a whole repo was effectively unaudited in CI while it audited fine from a developer's own gh auth. (That is why the stale vendored spec there was visible locally but never in a run.) The publish-bot App is installed org-wide (repository_selection=all) with contents:write, so an installation token scoped with `owner:` and no `repositories:` covers every repo the audit touches. Strictly better reads, no new secret, nothing to expire -- unlike a PAT, which is the same rot-by-expiry shape as the bugs this audit exists to catch. This does NOT by itself restore per-repo issue emission. The App's permissions are {actions:read, contents:write, metadata:read} -- it has no `issues` scope at all, which is why wiring it earlier would not have helped. Granting the App `issues: write` and approving it on the org installation is the one remaining step, and needs no further change here: emission starts working the moment the permission exists. Until then it falls back to the aggregate issue on this repo and says so loudly. Precedence is PAT > App token > GITHUB_TOKEN, so setting DRIFT_AUDIT_TOKEN still overrides. The mint step is continue-on-error: a token hiccup degrades to GITHUB_TOKEN rather than failing the audit. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Ua8CevgSHNqoyiy7ziZjHk --- .github/workflows/drift-audit.yml | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/.github/workflows/drift-audit.yml b/.github/workflows/drift-audit.yml index 2601a14bc6..13c16fba8a 100644 --- a/.github/workflows/drift-audit.yml +++ b/.github/workflows/drift-audit.yml @@ -56,10 +56,35 @@ jobs: with: python-version: '3.x' + # Mint an installation token for the publish-bot App. `owner:` with no + # `repositories:` scopes it to every repo the App is installed on, which + # is the whole org (repository_selection=all) -- so this ALREADY beats + # GITHUB_TOKEN for reads: the default token cannot see displayxr-shell-pvt + # at all, and the audit was silently degrading those to "could not fetch". + # + # It does NOT yet fix issue emission: the App's permissions are + # {actions:read, contents:write, metadata:read} -- no `issues` at all. Grant + # the App `issues: write` (and approve it on the org installation) and + # per-repo drift issues start working with no further change here. + # Until then emission falls back to one aggregate issue on this repo, + # loudly, and the job says so. + # + # continue-on-error so a token hiccup degrades to GITHUB_TOKEN rather than + # failing the audit outright. + - name: Mint App installation token + id: app-token + continue-on-error: true + uses: actions/create-github-app-token@v3 + with: + app-id: ${{ secrets.DISPLAYXR_APP_ID }} + private-key: ${{ secrets.DISPLAYXR_APP_PRIVATE_KEY }} + owner: DisplayXR + - name: Run drift audit env: - # Prefer the org-scoped PAT; fall back to the default token. - GH_TOKEN: ${{ secrets.DRIFT_AUDIT_TOKEN || secrets.GITHUB_TOKEN }} + # Order of preference: explicit PAT (if someone sets one) > App + # installation token (org-wide reads) > the default repo token. + GH_TOKEN: ${{ secrets.DRIFT_AUDIT_TOKEN || steps.app-token.outputs.token || secrets.GITHUB_TOKEN }} run: | # schedule -> emit issues; manual dispatch honours the input. if [ "${{ github.event_name }}" = "schedule" ] || \