feat(desktop): sign Windows installers via Azure Trusted Signing - #559
Open
Weegy wants to merge 1 commit into
Open
feat(desktop): sign Windows installers via Azure Trusted Signing#559Weegy wants to merge 1 commit into
Weegy wants to merge 1 commit into
Conversation
The existing Windows path expects a .p12 in WINDOWS_CSC_LINK_BASE64, which is
a dead end for any new certificate: since 2023-06-01 the CA/Browser Forum
requires every code-signing private key (OV *and* EV) to be generated and kept
in a FIPS 140-2 L2 / EAL4+ HSM, so no CA will issue an exportable file. As a
result Windows installers currently ship unsigned and SmartScreen shows an
'unknown publisher' warning.
Azure Trusted Signing (rebranded Azure Artifact Signing) solves this without a
hardware token, so it works on GitHub-hosted runners. Verified against the
pinned app-builder-lib@25.1.8 schema rather than assumed:
- win.azureSignOptions already exists in 25.1.8 — no electron-builder
upgrade needed
- required fields are endpoint, codeSigningAccountName, certificateProfileName
- electron-builder installs the TrustedSigning PowerShell module itself
(Install-Module -Name TrustedSigning -RequiredVersion 0.4.1) and reads
credentials via Azure EnvironmentCredential, which is why the three
AZURE_* credential names are fixed by Azure rather than chosen here
The three account coordinates are passed on the CLI instead of being written
into electron-builder.yml, so the committed config stays generic — a fork
without these secrets builds unsigned rather than failing against someone
else's Azure account.
Also adds an always-on Windows verification gate, mirroring the macOS one: it
runs whenever signing was configured, so 'secrets present but the installer
came out unsigned' fails the build instead of reaching users. It additionally
requires a trusted timestamp, without which the signature would expire with
the certificate. Uses Get-AuthenticodeSignature rather than signtool.exe to
avoid depending on a Windows SDK path.
The legacy .p12 path is kept for pre-2023 certificates but is now only used
when the Azure secrets are absent.
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.
Problem
Windows installers currently ship unsigned — SmartScreen shows an "unknown publisher" warning. Unlike the macOS defect in #558 the installer still runs, so this is a product-quality issue rather than an outage, but it hurts conversion on every download.
The existing path in the workflow expects a
.p12inWINDOWS_CSC_LINK_BASE64, and that is a dead end for any new certificate: since 2023-06-01 the CA/Browser Forum requires every code-signing signing key — OV and EV — to be generated and held in a FIPS 140-2 Level 2 / EAL4+ HSM. No CA will issue an exportable file any more, so that secret can only ever be filled from a pre-2023 certificate.Approach: Azure Trusted Signing
Azure Trusted Signing (rebranded Azure Artifact Signing in 2026) keeps the signing material in Microsoft's HSM and signs over an API, so it needs no hardware token and works on GitHub-hosted runners. ~$9.99/month, available to verified EU businesses.
Everything below was verified against the pinned
app-builder-lib@25.1.8, not assumed:win.azureSignOptionsin 25.1.8 schemaendpoint,codeSigningAccountName,certificateProfileNameInstall-Module -Name TrustedSigning -RequiredVersion 0.4.1)EnvironmentCredential→ the threeAZURE_*names are fixed by Azure, not chosen hereChanges
.github/workflows/desktop-apps.yml--config.win.azureSignOptions.*flags; fails fast ifAZURE_CLIENT_IDis set but any sibling is empty.github/workflows/desktop-apps.yml.github/workflows/desktop-apps.yml.p12path kept, but only used when the Azure secrets are absent; header documents why it is legacydesktop/README.mdThe three account coordinates are passed on the CLI rather than written into
electron-builder.yml, so the committed config stays generic — a fork without these secrets builds unsigned instead of failing against byte5's Azure account.Verification gate
Mirrors the macOS gate added in #558. It runs whenever signing was configured, so "secrets are present but the installer came out unsigned" fails the build instead of going green and reaching users. It also requires a trusted timestamp — without a countersignature the signature stops validating once the certificate expires. Uses
Get-AuthenticodeSignaturerather thansigntool.exe, so there is no Windows SDK path to locate.That failure mode is not hypothetical: it is exactly how v0.56.0 and v0.57.0 shipped a macOS app that could not be opened at all.
Verified so far
actionlintclean (the two info-levelSC2086hits are the intentional word-splitting on${EB_NOTARIZE:-}/${EB_WIN_SIGN:-})Not yet validated end-to-end
This cannot be tested until the Azure Trusted Signing account exists. Required setup on the byte5 Azure tenant:
AZURE_TENANT_ID,AZURE_CLIENT_ID,AZURE_CLIENT_SECRET,AZURE_SIGN_ENDPOINT,AZURE_SIGN_ACCOUNT,AZURE_SIGN_CERT_PROFILEUntil then this branch is a no-op for Windows: no Azure secrets → no
EB_WIN_SIGNflags → unsigned build, exactly as today. Merging it early is safe; it simply activates once the secrets land.Test plan
azureSignOptionssupport confirmed in the pinned electron-builderDesktop appsdispatched; Windows job signs and the gate passes.exeshows a valid, timestamped signature with the byte5 publisherNeed help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.