From 024f16604f24de71bbf75c890a2e57d969e1127a Mon Sep 17 00:00:00 2001 From: Alexander Rymdeko-Harvey <8761706+killswitch-GUI@users.noreply.github.com> Date: Mon, 19 Oct 2026 13:36:10 -0400 Subject: [PATCH] ci: refresh Windows release signing credentials --- .github/workflows/release.yml | 30 ++++++++++--- scripts/ci/desktop-contract.test.mjs | 65 +++++++++++++++++++++++++++- 2 files changed, 87 insertions(+), 8 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bb7f3f14..d6f008f0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1101,13 +1101,6 @@ jobs: npm ci --ignore-scripts npm audit --audit-level=high - - name: Authenticate to Azure using GitHub OIDC - uses: azure/login@a641126d1b8aa4d1fa005f4f92df94a3a4c4c906 # v3 - with: - client-id: ${{ secrets.AZURE_CLIENT_ID }} - tenant-id: ${{ secrets.AZURE_TENANT_ID }} - subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - - name: Build pinned functional-preview browser without launching it if: env.COLOSSUS_DESKTOP_BROWSER_FUNCTIONAL_PREVIEW == '1' shell: pwsh @@ -1125,6 +1118,14 @@ jobs: $images.FullName | Out-File -FilePath $env:GITHUB_ENV -Append 'COLOSSUS_IMAGES_END' | Out-File -FilePath $env:GITHUB_ENV -Append + - name: Authenticate browser signing with fresh GitHub OIDC + if: env.COLOSSUS_DESKTOP_BROWSER_FUNCTIONAL_PREVIEW == '1' + uses: azure/login@a641126d1b8aa4d1fa005f4f92df94a3a4c4c906 # v3 + with: + client-id: ${{ secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + - name: Sign functional-preview browser binaries before inventory if: env.COLOSSUS_DESKTOP_BROWSER_FUNCTIONAL_PREVIEW == '1' uses: azure/artifact-signing-action@c7ab2a863ab5f9a846ddb8265964877ef296ee82 # v2 @@ -1149,6 +1150,14 @@ jobs: shell: pwsh run: ./scripts/package-desktop-windows.ps1 -Phase build + # Cold builds can outlive Azure's token and the short-lived federation assertion. + - name: Authenticate nested binary signing with fresh GitHub OIDC + uses: azure/login@a641126d1b8aa4d1fa005f4f92df94a3a4c4c906 # v3 + with: + client-id: ${{ secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + - name: Sign bundled sidecar, CLI, and ripgrep uses: azure/artifact-signing-action@c7ab2a863ab5f9a846ddb8265964877ef296ee82 # v2 with: @@ -1167,6 +1176,13 @@ jobs: shell: pwsh run: ./scripts/package-desktop-windows.ps1 -Phase bind + - name: Authenticate installer signing with fresh GitHub OIDC + uses: azure/login@a641126d1b8aa4d1fa005f4f92df94a3a4c4c906 # v3 + with: + client-id: ${{ secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + - name: Bundle NSIS and sign patched app, uninstaller, and installer shell: pwsh run: ./scripts/package-desktop-windows.ps1 -Phase bundle diff --git a/scripts/ci/desktop-contract.test.mjs b/scripts/ci/desktop-contract.test.mjs index 18c94120..8e8cce26 100644 --- a/scripts/ci/desktop-contract.test.mjs +++ b/scripts/ci/desktop-contract.test.mjs @@ -1368,7 +1368,70 @@ test("Developer Preview compilation and ad-hoc signing use separate runners", () assert.match(signedWindowsJob, /environment: release-signing/u); assert.match(signedWindowsJob, /id-token: write/u); assert.match(signedWindowsJob, /COLOSSUS_DESKTOP_TEAM_ID: OBSCURITY_LABS_LLC/u); - assert.match(signedWindowsJob, /azure\/login@[0-9a-f]{40}/u); + const signedSteps = signedWindowsJob + .replaceAll("\r\n", "\n") + .split(/^ - /mu) + .slice(1); + const signingStepIndex = (name) => { + const matches = signedSteps.flatMap((step, index) => + step.startsWith(`name: ${name}\n`) ? [index] : [], + ); + assert.equal(matches.length, 1, `Expected one signed Windows step: ${name}`); + return matches[0]; + }; + const previewGuard = "env.COLOSSUS_DESKTOP_BROWSER_FUNCTIONAL_PREVIEW == '1'"; + for (const [buildName, authName, signingName, guard] of [ + [ + "Build pinned functional-preview browser without launching it", + "Authenticate browser signing with fresh GitHub OIDC", + "Sign functional-preview browser binaries before inventory", + previewGuard, + ], + [ + "Build unsigned desktop inputs", + "Authenticate nested binary signing with fresh GitHub OIDC", + "Sign bundled sidecar, CLI, and ripgrep", + null, + ], + [ + "Bind signed nested binaries into the desktop executable", + "Authenticate installer signing with fresh GitHub OIDC", + "Bundle NSIS and sign patched app, uninstaller, and installer", + null, + ], + ]) { + const authIndex = signingStepIndex(authName); + assert.equal( + authIndex, + signingStepIndex(buildName) + 1, + `${authName} must follow its build/bind boundary`, + ); + assert.equal( + signingStepIndex(signingName), + authIndex + 1, + `${authName} must immediately precede signing`, + ); + const auth = signedSteps[authIndex]; + assert.match( + auth, + /^ uses: azure\/login@a641126d1b8aa4d1fa005f4f92df94a3a4c4c906(?: # v3)?$/mu, + ); + for (const [input, secret] of [ + ["client-id", "AZURE_CLIENT_ID"], + ["tenant-id", "AZURE_TENANT_ID"], + ["subscription-id", "AZURE_SUBSCRIPTION_ID"], + ]) { + assert.ok( + auth.split("\n").includes(" " + input + ": ${{ secrets." + secret + " }}"), + `${authName} must retain its ${input} binding`, + ); + } + const authGuard = auth.match(/^ if: (.+)$/mu)?.[1] ?? null; + const signingGuard = signedSteps[authIndex + 1].match(/^ if: (.+)$/mu)?.[1] ?? null; + assert.equal(authGuard, guard, `${authName} must run exactly when signing runs`); + assert.equal(signingGuard, guard, `${signingName} guard changed`); + } + assert.equal((signedWindowsJob.match(/azure\/login@/gu) ?? []).length, 3); assert.equal((signedWindowsJob.match(/azure\/artifact-signing-action@[0-9a-f]{40}/gu) ?? []).length, 2); const browserSign = signedWindowsJob.indexOf("Sign functional-preview browser binaries before inventory"); const browserSeal = signedWindowsJob.indexOf("Seal exact signed browser bytes for independent sidecar compilation");