feat-win-code-signing
⚡ Improvements
Signed Windows builds (Azure Artifact Signing)
Goal: Windows installers and executables were unsigned, so endpoint security software (e.g. Cortex XDR) and SmartScreen flagged them as "suspicious" and blocked installs and auto-updates on client machines.
Solution: Authenticode code signing via Azure Artifact Signing (ex-Trusted Signing), performed with jsign directly on the existing Linux CI image (no Windows runner needed). Applied on release jobs only.
Features:
- Windows installer, app executable and uninstaller are now digitally signed as
BLOCKCHAINYOURIP(SHA-256, timestamped). - Prevents false-positive security blocks during install and updates.
verifyUpdateCodeSignatureenabled so auto-updates validate the publisher.
Implementation Details:
- Custom electron-builder sign hook (
win.signtoolOptions.sign) calling jsign withstoretype TRUSTEDSIGNING(keystore = regional endpoint, alias =account/profile, automatic timestamping). .windows_signCI template: setsWIN_SIGN=true, downloads jsign, fetches an Entra ID OAuth token (client_credentials), signs. Extended bypkg:win:beta,pkg:win:beta:prod,pkg:win:stableonly — internal snapshots (pkg:win:feat,pkg:win:feat:prod) stay unsigned.- Signing is gated by the
WIN_SIGNflag (default off): the sign hook skips unlessWIN_SIGN=true, so non-release Windows builds package cleanly without Azure credentials. WhenWIN_SIGN=true, any missing Azure variable is a hard error — a release can never ship silently unsigned. - Azure creds via masked CI/CD variables (
AZURE_*), scoped Devlab + Production (single Public Trust profile shared beta/prod). ci-builderimage bumped to3.2withdefault-jre-headless(jsign runs on the JVM).- Snapshot publish job renamed
publish:feat:test→publish:snapshot.
Files Modified:
package.json-win.signtoolOptions(custom sign, sha256, publisherName) +verifyUpdateCodeSignaturepackage_scripts/sign-windows.cjs- jsign sign hook (new).gitlab-ci.yml-.windows_signtemplate, wiring on release jobs, image3.2,publish:snapshotrenamedocker/Dockerfile- adddefault-jre-headlessfor jsign