Repository navigation
ci(release): sign Windows binaries and MSI via SignPath (#7207) - #7356
Merged
Merged
Conversation
Submit the standalone ocx.exe and the desktop MSI to SignPath Foundation from the release workflow, verify the returned Authenticode signatures on the Windows runner, and regenerate the Tauri updater signature over the signed MSI before the assets are renamed, checksummed and verified. Signing never blocks a release: missing or partial configuration, SignPath outages, timeouts, rejections and verification failures all keep the unsigned file with a warning, and a test-signing policy never signs a real release. A dispatch-only Windows signing test workflow exercises test-signing end to end without publishing.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Contributor
|
Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configuration
📒 Files selected for processing: 22
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Contributor
|
✅ Deterministic PR hygiene checks passed. |
3 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Wires Windows Authenticode code signing into the release workflow through SignPath Foundation for #7207, where Kaspersky and VirusTotal flag the unsigned
ocx.exe. Signing is layered onto the release so it can never block or fail one. That matters because the release-signing certificate has not been issued yet and theSIGNPATH_SIGNING_POLICY_SLUGvariable is stilltest-signing.What a run does now:
dry-run: true)SIGNPATH_API_TOKEN(forks, unconfigured copies)::notice::::warning::::warning::test-signing(today)::notice::; a test certificate never shipsrelease-signing::warning::::warning::Standalone (
package-standalone,bun-windows-x64). After the smoke test,ocx.exeis uploaded alone (it sits at the zip root, matchingwindows-standalone-zip), submitted with the officialsignpath/github-action-submit-signing-requestpinned to v3.0f6d04783…, verified, and swapped in. The zip and its.sha256are then built from the signed binary.Desktop MSI (
package-desktop,x86_64-pc-windows-msvc). Aftertauri buildand beforecollect-release-assets, the.msiis uploaded and signed withwindows-msi-zip, which deep-signs the app exe, the bundledocx.exe, and the MSI itself. Authenticode rewrites the MSI, so the Tauri updater signature is regenerated over the signed bytes withtauri signer signand the sameTAURI_SIGNING_PRIVATE_KEY.verify-releasethen checks that.sigagainst the final MSI and writeslatest.jsonfrom it, exactly as before.Swap safety (
scripts/ci/apply-signed-windows-artifact.ps1). Everything that can fail runs on a staged copy first: the SignPath outcome, the returned file, Authenticode verification, the signedocx.exe --version, and the updater re-signature. Only then are the MSI and its.sigswapped in together, and an error mid-swap restores both originals. A failure therefore never leaves a signed MSI next to a stale.sig, which would otherwise failverify-release.Verification (
scripts/ci/verify-authenticode.ps1). Built-in tools only:Get-AuthenticodeSignature,msiexec /ato expand the MSI into an administrative image (nothing is installed), and the hosted image's Windows SDKsigntool. It checksocx.exe, the MSI, and every.exeinside the MSI, requiringocx.exeand at least two executables. Underrelease-signingit requiresStatus Valid, aCN=SignPath Foundationsigner, a timestamp, andsigntool verify /pa /v. Undertest-signing, where the self-signed root is untrusted on the runner, it requires every file to carry a hash-valid signature and all files to share one signer. A second signer would mean an already-signed third-party file got re-signed, which the Foundation policy forbids.Non-publishing test path. A new
.github/workflows/windows-signing-test.yml(Windows signing test) is dispatch-only and takes no inputs. It buildsocx.exeand the MSI onwindows-latest, signs both withtest-signing(hardcoded, so it never spends a release approval), verifies them, links the SignPath request in the job summary, and keeps the test-signed files as 7-day workflow artifacts. Unlike the release path, it goes red on any failure, because a green run is the evidence it exists to produce. It publishes, tags and attaches nothing.Gating and permissions. The decision lives in
scripts/ci/windows-signing-plan.shso the gates are testable. Both packaging jobs gainactions: read(the SignPath action reads the job and downloads the artifact) next to the existingcontents: read; nothing else is broadened. Every job on the signing path runs on GitHub-hosted runners, as SignPath OSS requires. The Windows legs' job timeouts rise to 90 and 105 minutes because a release-signing request can wait up to 3600 s for manual approval; the other legs keep 25 and 45.Docs. New page Windows Code Signing at
docs-site/src/content/docs/reference/code-signing.md. It covers the Code signing policy with the SignPath-required wording (Free code signing provided by SignPath.io, certificate by SignPath Foundation; committers, reviewers and approvers: lidge-jun; the privacy statement), how users verify a signature, what gets signed, the policy table above, and how to flip torelease-signing. The README and all 7 locale READMEs gain a "Code signing policy" section and an updated Windows row (the i18n manifest hash is bumped), and the desktop and installation guides link the page.Decisions made autonomously (HOTL)
continue-on-errorand degrades to unsigned with a warning. Once release-signing is live and proven, a fail-closed switch (for example aSIGNPATH_REQUIREDvariable) can be added as a follow-up.release-signing, a dry run opens two signing requests that each need approval (or ship unsigned after the wait). The test workflow is the cheap path for exercising signing..nodekeyring addons stay unsigned. SignPath Foundation forbids signing third-party binaries with its certificate, but allows including them unsigned. No artifact-configuration change is proposed for them.Maintainer actions
SIGNPATH_SIGNING_POLICY_SLUGtorelease-signing. No code change is needed.ocx.execarries no Windows version resource. Proposed XML once that metadata exists (a separate change would pass bun's--windows-title/--windows-versionflags):Refs #7207. Do not close #7207 yet: it stays open until
release-signingis live and a signed release has shipped.Verification
bun test tests/ci-workflows/release-windows-signing.test.ts: 21 pass. This covers the decision matrix (bash), workflow gates and step order, the unsigned-artifact names not matchingstandalone-*/desktop-*, hosted runners, and permissions. It also runs swap behavior under PowerShell 7.6 with a fake verifier and fakebunx: a verified swap regenerates.sig; with no key the stale.sigis removed; a failed request, failed verification or failed re-signature each keep the original MSI and.sigwith a warning;-FailOnErrorgoes red; both.ps1files parse. The pwsh cases skip wherepwshis absent; the hosted Ubuntu image ships it.bun test tests/ci-workflows(Bun 1.4.3): 1575 pass, 8 fail in one parallel run. The 8 (release-helper,skill-ocxchapter) are 2–5 s subprocess tests that timed out under host contention; rerun in isolation they pass 40/40 and 8/8. One pre-existing contract test now selects the release upload by artifact name, since the standalone job gained a secondupload-artifactstep.tests/test-layout*.test.ts: 27 pass.bun run typecheck,bun run privacy:scanandbun run structure:checkpass, as doesactionlintonrelease.ymlandwindows-signing-test.yml.docs-sitebun run buildpasses (585 pages, internal link check).bun run testwas not run locally: concurrent worktrees made the parallel run time out on unrelated subprocess tests (above). Full-suite coverage is left to CI.Windows signing testworkflow can only be dispatched once it exists on the default branch (main), so the test-signed run happens after this lands and is promoted. Independent review: gpt-6.1-sol and gemini-4-argon both reported no findings (read-only reviews of the full diff).Checklist