Goal
Make installs warning-free — no Windows SmartScreen "unrecognized app" block, no macOS Gatekeeper "unidentified developer" / "damaged" prompt. This is the last piece of a compelling one-click install. Signing/notarization require credentials only you can obtain (Apple/CA/Azure accounts), so this is your checklist. I'll wire all the code/CI once the secrets exist — see "What I'll do" at the bottom.
Testing doesn't need signing — an unsigned Windows installer for test is being produced separately (you click through SmartScreen once). This issue is for the shippable, warning-free path.
Windows
Pick one. Azure Trusted Signing is recommended (cheap, no hardware token, gives EV-grade SmartScreen reputation):
Option A — Azure Trusted Signing (recommended)
- An Azure subscription (any).
- Create a Trusted Signing account + a Certificate Profile (Azure Portal → Trusted Signing). ~$9.99/mo.
- Complete identity verification (individual or organization) — this is the gating step; can take a few days.
- Create a service principal (App Registration) with the Trusted Signing Certificate Profile Signer role on the account.
- Add these GitHub Actions secrets (repo → Settings → Secrets and variables → Actions):
AZURE_TENANT_ID
AZURE_CLIENT_ID
AZURE_CLIENT_SECRET
AZURE_TS_ENDPOINT (e.g. https://eus.codesigning.azure.net)
AZURE_TS_ACCOUNT (account name)
AZURE_TS_PROFILE (certificate profile name)
Option B — OV/EV code-signing certificate (CA)
- Buy an OV (software-based) or EV (hardware-token/cloud-HSM) cert from DigiCert/Sectigo/etc. OV is easiest for CI; EV gets instant SmartScreen reputation but needs an HSM/cloud-signing service.
- Export the cert as a password-protected
.pfx, base64-encode it, and add:
WIN_CSC_LINK = base64 of the .pfx
WIN_CSC_KEY_PASSWORD = the .pfx password
- (EV via a cloud HSM uses that provider's signing tool instead — tell me which and I'll wire it.)
macOS
- Apple Developer Program enrollment ($99/yr).
- Create a Developer ID Application certificate (developer.apple.com → Certificates) → install in Keychain → export as a password-protected
.p12. Add:
MAC_CSC_LINK = base64 of the .p12
MAC_CSC_KEY_PASSWORD = the .p12 password
- Notarization via an App Store Connect API key (notarytool): create a key (App Store Connect → Users and Access → Integrations → App Store Connect API), download the
.p8. Add:
APPLE_API_KEY = base64 of the .p8 (or paste contents)
APPLE_API_KEY_ID
APPLE_API_ISSUER (issuer UUID)
APPLE_TEAM_ID (your 10-char team ID)
(Alternative to the API key: APPLE_ID + APPLE_APP_SPECIFIC_PASSWORD + APPLE_TEAM_ID. The API key is preferred for CI.)
What I'll do once the secrets exist
- Wire
win.signtoolOptions/azureSignOptions and mac.notarize (hardened runtime) into app/electron-builder.config.cjs.
- Flip
BUILD_SIGNED in app/src/main/updater.ts so auto-update is enabled for signed builds.
- Enable the tag pipeline in
.github/workflows/release.yml (uncomment the windows/mac installer jobs — the frozen-engine build steps are already proven by the frozen-smoke CI job — add on: push: tags: ['v*'], and --publish always to GitHub Releases).
- Verify a signed/notarized build installs warning-free on both OSes.
References (in-repo)
app/electron-builder.config.cjs — signing TODO comments + where the options go.
.github/workflows/release.yml — the stubbed pipeline + commented signed-build skeleton.
app/src/main/updater.ts — BUILD_SIGNED gate.
🤖 Generated with Claude Code
Goal
Make installs warning-free — no Windows SmartScreen "unrecognized app" block, no macOS Gatekeeper "unidentified developer" / "damaged" prompt. This is the last piece of a compelling one-click install. Signing/notarization require credentials only you can obtain (Apple/CA/Azure accounts), so this is your checklist. I'll wire all the code/CI once the secrets exist — see "What I'll do" at the bottom.
Windows
Pick one. Azure Trusted Signing is recommended (cheap, no hardware token, gives EV-grade SmartScreen reputation):
Option A — Azure Trusted Signing (recommended)
AZURE_TENANT_IDAZURE_CLIENT_IDAZURE_CLIENT_SECRETAZURE_TS_ENDPOINT(e.g.https://eus.codesigning.azure.net)AZURE_TS_ACCOUNT(account name)AZURE_TS_PROFILE(certificate profile name)Option B — OV/EV code-signing certificate (CA)
.pfx, base64-encode it, and add:WIN_CSC_LINK= base64 of the.pfxWIN_CSC_KEY_PASSWORD= the.pfxpasswordmacOS
.p12. Add:MAC_CSC_LINK= base64 of the.p12MAC_CSC_KEY_PASSWORD= the.p12password.p8. Add:APPLE_API_KEY= base64 of the.p8(or paste contents)APPLE_API_KEY_IDAPPLE_API_ISSUER(issuer UUID)APPLE_TEAM_ID(your 10-char team ID)(Alternative to the API key:
APPLE_ID+APPLE_APP_SPECIFIC_PASSWORD+APPLE_TEAM_ID. The API key is preferred for CI.)What I'll do once the secrets exist
win.signtoolOptions/azureSignOptionsandmac.notarize(hardened runtime) intoapp/electron-builder.config.cjs.BUILD_SIGNEDinapp/src/main/updater.tsso auto-update is enabled for signed builds..github/workflows/release.yml(uncomment the windows/mac installer jobs — the frozen-engine build steps are already proven by thefrozen-smokeCI job — addon: push: tags: ['v*'], and--publish alwaysto GitHub Releases).References (in-repo)
app/electron-builder.config.cjs— signing TODO comments + where the options go..github/workflows/release.yml— the stubbed pipeline + commented signed-build skeleton.app/src/main/updater.ts—BUILD_SIGNEDgate.🤖 Generated with Claude Code