Skip to content

Sign the Windows executables through SignPath - #753

Open
PathGao wants to merge 1 commit into
masterfrom
ci/windows-authenticode-signpath
Open

PathGao wants to merge 1 commit into
masterfrom
ci/windows-authenticode-signpath

Conversation

@PathGao

@PathGao PathGao commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

What this is

Windows Authenticode signing through SignPath Foundation, using the four strings @alecdotdev posted in #562. Ref #562, #334, #466, #722.

Mechanism

One signing request covers all four executables — SignPath signs the contents of one Actions artifact and an approver releases it by hand — but x64 and arm64 are two matrix entries, and each uploaded straight to the release page. So the signing is a job of its own: the matrix hands its build over as an artifact, sign-windows collects both, submits one request, and is the only place a Windows file reaches the release. An approval that never comes leaves the draft without Windows assets rather than with unsigned ones.

Authenticode rewrites the installer's bytes, and *-setup.exe.sig is a minisign signature over the pre-signing ones. Shipping that makes every Windows install reject its next update — the same defect the repacked AppImage had, fixed the same way: re-sign from the signed file, then let generate-update-feed read the signatures back off the release.

Scope

Without SIGNPATH_API_TOKEN the job uploads what the matrix built, unsigned, and the release notes keep the SmartScreen note — both keyed on that one secret, so a release cannot claim to be signed when it is not. Same shape as the macOS certificate, for the reason #294 was closed: a release must not be blocked on credentials nobody has configured yet.

The four non-secret values are in the job rather than in secrets, and RELEASING.md gets a one-time setup step 8 saying so, plus what the SignPath side needs — the GitHub App, the trusted build system, the artifact configuration, an approver.

Not here: signing the copy of Markpad an NSIS installer unpacks. Nothing can reach inside an installer after it is built, so that would be a second build pass and a second approval, and what people report — SmartScreen on the download, the heuristic on the portable .exe — is on the files this signs.

Tests

Four in scripts/releaseWorkflow.test.ts, all matching workflow text, which is what a workflow makes checkable: no gh release upload of an .exe in the matrix; one signing request per release over four collected executables; the .sig regenerated after the signed executables land and before the upload, with generate-update-feed waiting on the job; and the upload not gated on the token while every SignPath step is. The existing "RELEASING.md names the signing secrets the workflow reads" now reads the new job too.

Each was falsified: putting a release upload back in the matrix, asking for two files instead of four, moving the re-sign ahead of the signed copy, gating the upload on the token, dropping sign-windows from the feed's needs, and renaming the secret in RELEASING.md each turn exactly one of them red.

Verification

macOS 26.6.2, Node 24.16.0.

npm audit
npm run check
npm test
npx vitest run

0 vulnerabilities, 831 files / 0 errors, 1033 pass (was 1029), 434 pass.

Not verified: the release path itself. build.yml is workflow_dispatch only, so nothing here has run — the first proof is 2.7.7, and it is also the first time the SignPath side is exercised end to end. cargo test not run; no Rust in the diff.

🤖 Generated with Claude Code

@PathGao

PathGao commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator Author

Before merging: the SIGNPATH_API_TOKEN secret currently in the repository belongs to a SignPath trial organization, which cannot have a trusted build system linked — the connector rejects a submission from it, so the Windows job would fail and upload nothing. Delete the secret first and this merges safely; the job then uploads what the matrix built, unsigned, as today. Details in #562. The four SignPath values here are the trial's and get swapped when the Foundation organization exists.

@alecdotdev

Copy link
Copy Markdown
Collaborator

@PathGao secret deleted successfully. is this the last merge before 2.7.7 is ready to cut?

@PathGao

PathGao commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator Author

@alecdotdev Yes — this is the last one. Nothing else is open and master is green.

But don't merge it yet. Deleting the token made the merge safe; it didn't get us signing. Merging today gives you an unsigned 2.7.7, and the whole reason this release was worth waiting for is that it would be the first signed one.

The step left is yours, and it is a form: https://signpath.org/apply. The organization those four strings came from is the free trial, and a trial cannot have a trusted build system — which the open-source programme requires. You can't fix that from inside app.signpath.io; SignPath creates the Foundation organization themselves after they verify the project. On the form, Build System is GitHub and the repository is this one. Markpad qualifies — BSD-3-Clause, released, maintained, documented.

Everything else is already written down for you:

When the Foundation organization exists, send me its four strings — organization id, project slug, signing policy slug, artifact configuration slug. I swap the three lines here, you add SIGNPATH_API_TOKEN back, then merge and cut. That is 2.7.7 signed on its first run.

If the application drags on, tell me and we cut 2.7.7 unsigned instead. Nothing else in the release is waiting on this.

@alecdotdev

Copy link
Copy Markdown
Collaborator

@PathGao okay got it, i think the org is still under review then. ill update you when approved

@PathGao

PathGao commented Sep 15, 2026

Copy link
Copy Markdown
Collaborator Author

@alecdotdev have you got the sign?

@PathGao

PathGao commented Sep 15, 2026

Copy link
Copy Markdown
Collaborator Author

I may sign an apple developer today so probably our macos version will also be signed by me

@alecdotdev

Copy link
Copy Markdown
Collaborator

@PathGao no response yet. let me know if you do go through with the apple dev part and if theres any secrets id need to add

@PathGao

PathGao commented Sep 16, 2026

Copy link
Copy Markdown
Collaborator Author

@PathGao no response yet. let me know if you do go through with the apple dev part and if theres any secrets id need to add

done. next time when you release,macos version will be signed by apple.

@PathGao

PathGao commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator Author

@alecdotdev on the SignPath wait: it has been at least nine days since you said the organization was under review, and Markpad still isn't on signpath.org/projects. SignPath publishes no review time for the Foundation programme — other projects report a few weeks — so this is not yet unusual, but it is worth a nudge.

The review lives in their inbox, not here: mail support@signpath.io with the project name, the repository URL and the date you submitted the form, and ask where the application stands. That is faster than waiting for the form to answer on its own.

@PathGao
PathGao force-pushed the ci/windows-authenticode-signpath branch from 0df8a58 to dea9596 Compare September 17, 2026 19:53
@alecdotdev

Copy link
Copy Markdown
Collaborator

@PathGao good news, Markpad [OSS] application approved and can move forward:

The review of your project has been finished and we are happy to announce that your project is > eligible for the SignPath Foundation program.

You will receive two emails from SignPath: an invitation to your new OSS organization, and a > confirmation request for the CI user's email address. These can arrive in either order. Please create > your SignPath account first, accept the organization invitation with it, and only then confirm the CI > user address – the confirmation cannot be completed before the invitation is accepted.

Once you are in, you can start to

set up your project and artifact configuration (GitHub requires you to put it in a zip file): > https://about.signpath.io/documentation/artifact-configuration/
configure the GitHub Actions integration: https://about.signpath.io/documentation/> trusted-build-systems/github

Then you can start signing using the provided self-signed test certificate. Once you're all set, > we'll review the setup and order the actual production certificate and import it into your > organization.

new variables:

project slug: Markpad
slug: test-signing
org id: 49a1e96b-8b57-4ce2-a082-a28177377bc8

can add the SIGNPATH_API_TOKEN for the CI user once any changes are ready. let me know if theres anything else needed for this

@PathGao
PathGao force-pushed the ci/windows-authenticode-signpath branch from dea9596 to 153d327 Compare October 10, 2026 00:57
@PathGao

PathGao commented Oct 10, 2026

Copy link
Copy Markdown
Collaborator Author

@alecdotdev Rebased onto master (the conflict was #935 merging the two Windows upload steps) and swapped in the new org id, project slug Markpad and policy test-signing. Workflow tests pass.

Still needed from you:

  1. The artifact configuration slug. I left initial, SignPath's default name; tell me if yours is different. The XML to paste is in Packaging: one fix removes half of this list, and the rest is Linux #562 (comment).
  2. In the new OSS organization: install the SignPath GitHub App on this repository and link GitHub.com as the trusted build system for the project. Without that the request is rejected before signing.
  3. Accept the invitation, then confirm the CI user email, then add SIGNPATH_API_TOKEN back.

Please don't merge or cut 2.7.7 on test-signing. That policy signs with SignPath's self-signed test certificate, which Windows does not trust, and the release notes would still say the executables are signed. Once the token is in, I'll do a dry run from a throwaway version and delete the draft afterwards. SignPath then reviews the setup and issues the production certificate. I switch the policy to the production one, and then this merges and 2.7.7 ships signed.

@alecdotdev

Copy link
Copy Markdown
Collaborator

@PathGao

  1. artifact slug is still initial
  2. SignPath app installed to GitHub. linked as trusted build
  3. confirmed and adding token to secrets

will keep you updated once they reach back out

@PathGao

PathGao commented Oct 10, 2026

Copy link
Copy Markdown
Collaborator Author

@alecdotdev Thanks. SIGNPATH_API_TOKEN isn't in the repo secrets yet. SignPath reviews the setup only after a test signing has gone through, so they're waiting on us, not the other way round. Ping me once the token is in and I'll run the test-signing dry run.

@alecdotdev

Copy link
Copy Markdown
Collaborator

@PathGao added now

@PathGao

PathGao commented Oct 10, 2026

Copy link
Copy Markdown
Collaborator Author

@alecdotdev Dry run passed (run 38033533193, deleted afterwards). All four executables carry SignPath's test certificate, and the regenerated updater signatures verify against the signed installers and match latest.json. That's the "all set" SignPath asked for, so you can tell them the setup is ready for review. When the production certificate is in, send me the production signing policy slug. I'll switch it here, and then this can merge and the next release ships signed.

@PathGao

PathGao commented Oct 10, 2026

Copy link
Copy Markdown
Collaborator Author

@alecdotdev On timing: the next release goes out after I've reviewed #962, #963 and #964, and within a few days of SignPath issuing the production certificate. So this merges together with those, and that release is the first signed Windows build.

@PathGao

PathGao commented Oct 13, 2026

Copy link
Copy Markdown
Collaborator Author

@alecdotdev Did you tell SignPath the setup is ready, and have they replied?

@alecdotdev

Copy link
Copy Markdown
Collaborator

@PathGao sent them a confirmation oct 10th, still awaiting follow-up

@alecdotdev

Copy link
Copy Markdown
Collaborator

they replied:

Thank you for the ping und update on your part.

We’ll now review your signing setup and the signing requests you’ve submitted. As part of this, we’ll check that everything is configured correctly (for example origin verification, workflow setup, and policy usage). If everything looks good, we can proceed with releasing the production certificate to your organization in SignPath so you can use it in your regular release process. I’ll get back to you once the review is complete or if we need any clarification from your side.

One important heads-up:
unlike the self-signed test certificate, signing requests using the production certificate require manual approval in the SignPath UI. This is an expected behavior for Open Source projects using SignPath Foundation certificates, as we also need to verify what is signed and from what build (repo, etc..). It’s usually easiest to factor this into the workflow (for example by separating build and signing steps) once you switch over.

just awaiting subseq followup now.

@PathGao

PathGao commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator Author

Great!!!!

@PathGao

PathGao commented Oct 24, 2026

Copy link
Copy Markdown
Collaborator Author

How much is it going?

@PathGao

PathGao commented Oct 28, 2026

Copy link
Copy Markdown
Collaborator Author

@alecdotdev Any news from SignPath on the production certificate? I'm planning to release in the next couple of days.

@alecdotdev

Copy link
Copy Markdown
Collaborator

@PathGao haven't heard anything past the following since Oct 16th.

I’ll get back to you once the review is complete or if we need any clarification from your side.

I'll ping here as soon as that changes.

@PathGao
PathGao force-pushed the ci/windows-authenticode-signpath branch from 153d327 to ad01b77 Compare October 30, 2026 11:43
One signing request covers all four executables, so it lives in a job of
its own rather than in the two Windows matrix entries. The matrix hands
its build over as an artifact; nothing Windows reaches the release page
until the request comes back approved.

Authenticode rewrites the installer, so its `.sig` -- the minisign
signature the updater checks -- is regenerated from the signed file
before anything is uploaded. Without SIGNPATH_API_TOKEN the job uploads
what the matrix built, unsigned, and the release notes keep saying so.
@PathGao
PathGao force-pushed the ci/windows-authenticode-signpath branch from ad01b77 to a0cb583 Compare November 11, 2026 16:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants