From e6e3248c97fdab8f75d4f4771f028c3203854db5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Halber?= Date: Wed, 10 Jun 2026 14:36:47 -0700 Subject: [PATCH 1/4] chore: remove test azure oidc unused since sandbox was removed in monorepo --- .github/workflows/test-azure-oidc.yml | 33 --------------------------- 1 file changed, 33 deletions(-) delete mode 100644 .github/workflows/test-azure-oidc.yml diff --git a/.github/workflows/test-azure-oidc.yml b/.github/workflows/test-azure-oidc.yml deleted file mode 100644 index 1a3800fd..00000000 --- a/.github/workflows/test-azure-oidc.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: test-azure-oidc - -# Validates that the federated identity credentials and GitHub repo secrets -# are wired up correctly. Does NOT invoke Trusted Signing — only confirms the -# OIDC handshake and that az can authenticate as the configured principal. -# Safe to run before the (paid) Trusted Signing Account is created. - -on: - workflow_dispatch: - -permissions: - id-token: write - contents: read - -jobs: - oidc: - runs-on: ubuntu-latest - # Sandbox AAD app's federated credential trusts this environment only. - environment: sandbox-release - steps: - - name: Azure login (OIDC) - uses: azure/login@532459ea530d8321f2fb9bb10d1e0bcf23869a43 # v3.0.0 - with: - client-id: ${{ secrets.AZURE_CLIENT_ID }} - tenant-id: ${{ secrets.AZURE_TENANT_ID }} - subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - - - name: Confirm authenticated identity - run: | - az account show - echo - echo "Signed-in service principal:" - az ad sp show --id "${{ secrets.AZURE_CLIENT_ID }}" --query "{displayName: displayName, appId: appId}" -o table From 8680cd82773f60230e4faee6efce9e1756556614 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Halber?= Date: Fri, 12 Jun 2026 12:21:38 -0700 Subject: [PATCH 2/4] chore: update deprecated input --- .github/actions/sign-windows-artifacts/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/sign-windows-artifacts/action.yml b/.github/actions/sign-windows-artifacts/action.yml index cbe847cc..7bc48832 100644 --- a/.github/actions/sign-windows-artifacts/action.yml +++ b/.github/actions/sign-windows-artifacts/action.yml @@ -33,7 +33,7 @@ runs: - uses: azure/artifact-signing-action@c7ab2a863ab5f9a846ddb8265964877ef296ee82 # v2.0.0 with: endpoint: ${{ inputs.endpoint }} - trusted-signing-account-name: ${{ inputs.account-name }} + signing-account-name: ${{ inputs.account-name }} certificate-profile-name: ${{ inputs.cert-profile }} files-folder: target/distrib files-folder-filter: exe From 6433510cebeac5215b15f26e98df8829656a940f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Halber?= Date: Fri, 12 Jun 2026 15:31:13 -0700 Subject: [PATCH 3/4] chore: do not block whole ci if windows code signing fails --- .github/workflows/release-canary.yml | 1 + .github/workflows/release.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/release-canary.yml b/.github/workflows/release-canary.yml index 53658e0e..c3892d58 100644 --- a/.github/workflows/release-canary.yml +++ b/.github/workflows/release-canary.yml @@ -187,6 +187,7 @@ jobs: - name: Sign Windows artifacts if: ${{ runner.os == 'Windows' && env.HAS_AZURE_SIGNING == 'true' }} + continue-on-error: true uses: ./.github/actions/sign-windows-artifacts with: client-id: ${{ secrets.AZURE_CLIENT_ID }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ec5ba53a..0047574f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -222,6 +222,7 @@ jobs: - name: Sign Windows artifacts if: ${{ runner.os == 'Windows' && env.HAS_AZURE_SIGNING == 'true' }} + continue-on-error: true uses: ./.github/actions/sign-windows-artifacts with: client-id: ${{ secrets.AZURE_CLIENT_ID }} From 1eb5d7b3ad7a5b0804eb91964f964e46334850d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Halber?= Date: Fri, 12 Jun 2026 16:16:06 -0700 Subject: [PATCH 4/4] add: action checking if windows binaries were signed as seen in https://github.com/actions/runner/issues/2347, unsupported by github action at the moment so we need another action to watch the first one --- .../verify-windows-signature/action.yml | 61 +++++++++++++++++++ .github/workflows/release-canary.yml | 10 +++ .github/workflows/release.yml | 10 +++ 3 files changed, 81 insertions(+) create mode 100644 .github/actions/verify-windows-signature/action.yml diff --git a/.github/actions/verify-windows-signature/action.yml b/.github/actions/verify-windows-signature/action.yml new file mode 100644 index 00000000..6f3f1ec7 --- /dev/null +++ b/.github/actions/verify-windows-signature/action.yml @@ -0,0 +1,61 @@ +name: Verify Windows signature +description: Check that bt.exe binaries are validly Authenticode-signed; if not, post a neutral check run so the unsigned build is surfaced without failing the job. Stops being necessary once GitHub supports https://github.com/actions/runner/issues/2347 (opened 1st April 2020, 1500 reactions, still not done so we'll probably have to wait a few more years) + +inputs: + sign-outcome: + required: true + description: Outcome of the signing step (e.g. success/failure/skipped). + targets: + required: true + description: Human-readable build targets, used in the check-run name. + github-token: + required: true + description: Token with checks:write used to create the check run. + +runs: + using: composite + steps: + - name: Verify signature and report + shell: pwsh + env: + GH_TOKEN: ${{ inputs.github-token }} + SIGN_OUTCOME: ${{ inputs.sign-outcome }} + TARGETS: ${{ inputs.targets }} + run: | + $exes = Get-ChildItem -Path "target/distrib" -Filter "bt.exe" -Recurse -ErrorAction SilentlyContinue + $unsigned = @() + foreach ($exe in $exes) { + $sig = Get-AuthenticodeSignature $exe.FullName + if ($sig.Status -ne 'Valid') { + $unsigned += "$($exe.FullName) [$($sig.Status)]" + } + } + + if ($SIGN_OUTCOME -eq 'success' -and $unsigned.Count -eq 0) { + Write-Host "All bt.exe binaries are validly signed." + exit 0 + } + + $summary = if ($unsigned.Count -gt 0) { + "Code signing did not produce valid Authenticode signatures. The following binaries are unsigned and were shipped as-is:`n`n" + (($unsigned | ForEach-Object { "- $_" }) -join "`n") + } else { + "The Windows signing step failed (outcome: $SIGN_OUTCOME). Binaries were shipped unsigned." + } + + $body = @{ + name = "windows-signing ($env:TARGETS)" + head_sha = $env:GITHUB_SHA + status = "completed" + conclusion = "neutral" + output = @{ + title = "Windows binaries shipped unsigned" + summary = $summary + } + } | ConvertTo-Json -Depth 5 + + $body | gh api "repos/$env:GITHUB_REPOSITORY/check-runs" ` + --method POST ` + -H "Accept: application/vnd.github+json" ` + --input - + + Write-Host "::warning::$summary" diff --git a/.github/workflows/release-canary.yml b/.github/workflows/release-canary.yml index c3892d58..deb94d45 100644 --- a/.github/workflows/release-canary.yml +++ b/.github/workflows/release-canary.yml @@ -16,6 +16,7 @@ permissions: id-token: write issues: write pull-requests: write + checks: write env: CARGO_NET_GIT_FETCH_WITH_CLI: true @@ -186,6 +187,7 @@ jobs: echo "dist ran successfully" - name: Sign Windows artifacts + id: sign if: ${{ runner.os == 'Windows' && env.HAS_AZURE_SIGNING == 'true' }} continue-on-error: true uses: ./.github/actions/sign-windows-artifacts @@ -197,6 +199,14 @@ jobs: account-name: ${{ vars.AZURE_SIGNING_ACCOUNT_NAME }} cert-profile: ${{ vars.AZURE_SIGNING_CERT_PROFILE }} + - name: Verify Windows signature and report + if: ${{ runner.os == 'Windows' && env.HAS_AZURE_SIGNING == 'true' && always() }} + uses: ./.github/actions/verify-windows-signature + with: + sign-outcome: ${{ steps.sign.outcome }} + targets: ${{ join(matrix.targets, ', ') }} + github-token: ${{ secrets.GITHUB_TOKEN }} + - id: dist-files name: Post-build shell: bash diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0047574f..21fceab9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,6 +20,7 @@ concurrency: permissions: contents: write id-token: write + checks: write env: CARGO_NET_GIT_FETCH_WITH_CLI: true @@ -221,6 +222,7 @@ jobs: echo "dist ran successfully" - name: Sign Windows artifacts + id: sign if: ${{ runner.os == 'Windows' && env.HAS_AZURE_SIGNING == 'true' }} continue-on-error: true uses: ./.github/actions/sign-windows-artifacts @@ -232,6 +234,14 @@ jobs: account-name: ${{ vars.AZURE_SIGNING_ACCOUNT_NAME }} cert-profile: ${{ vars.AZURE_SIGNING_CERT_PROFILE }} + - name: Verify Windows signature and report + if: ${{ runner.os == 'Windows' && env.HAS_AZURE_SIGNING == 'true' && always() }} + uses: ./.github/actions/verify-windows-signature + with: + sign-outcome: ${{ steps.sign.outcome }} + targets: ${{ join(matrix.targets, ', ') }} + github-token: ${{ secrets.GITHUB_TOKEN }} + - id: dist-files name: Post-build shell: bash