# AeroFetch — Windows code signing Unsigned builds run, but Windows SmartScreen shows a blue **"Windows protected your PC"** prompt the first time each user runs the installer (they must click *More info → Run anyway*). This is the single biggest first-run friction when sharing AeroFetch. Code signing removes it (EV certificates remove it immediately; OV certificates build reputation over time/installs). **This step needs a certificate that can't live in the repo**, so it isn't wired on by default. The build is otherwise ready for it — electron-builder picks the cert up from environment variables with no `electron-builder.yml` changes required. ## What you need - An **Authenticode code-signing certificate** for Windows: - **OV (Organization Validation)** — cheaper; SmartScreen reputation accrues as more users install, so early downloads still see the prompt. - **EV (Extended Validation)** — pricier, usually on a hardware token / cloud HSM; clears SmartScreen immediately. Token-based EV can't be fed as a plain `.pfx` (see "HSM/EV" below). - The cert as a password-protected `.pfx`/`.p12` (for OV), or an HSM/cloud-signing setup (EV). ## Signing an OV `.pfx` locally electron-builder reads these env vars automatically: ```bash # PowerShell $env:CSC_LINK = "C:\path\to\codesign.pfx" # or a base64 string of the .pfx $env:CSC_KEY_PASSWORD = "" npm run build:win ``` ```bash # bash / CI export CSC_LINK="$(base64 -w0 codesign.pfx)" # base64 is convenient for CI secrets export CSC_KEY_PASSWORD="$PFX_PASSWORD" npm run build:win ``` electron-builder then signs `AeroFetch Setup .exe`, the portable `.exe`, and the app binary. No changes to `electron-builder.yml` are needed; if `CSC_LINK` is unset, the build proceeds **unsigned** (current behavior). ## CI (GitHub Actions sketch) Store the cert + password as encrypted secrets and export them before the build: ```yaml - name: Build (signed) env: CSC_LINK: ${{ secrets.WINDOWS_CSC_LINK }} # base64 of the .pfx CSC_KEY_PASSWORD: ${{ secrets.WINDOWS_CSC_KEY_PASSWORD }} run: npm run build:win ``` ## HSM / EV certificates EV certs (and many newer OV certs) ship on a hardware token or cloud HSM and can't be exported to a `.pfx`. Sign via a custom signing hook instead — set `win.sign` in `electron-builder.yml` to a script that invokes your provider's tool (Azure Trusted Signing, DigiCert KeyLocker, SSL.com eSigner, or `signtool` with the token). Each provider documents the exact `signtool` invocation; electron-builder calls your hook once per artifact with the file path. ## Verifying a signature ```powershell Get-AuthenticodeSignature ".\dist\AeroFetch Setup .exe" | Format-List # Status should be 'Valid'; SignerCertificate should be your cert. signtool verify /pa /v ".\dist\AeroFetch Setup .exe" ``` ## Notes - The LGPL ffmpeg + yt-dlp binaries shipped in `resources/bin` are third-party; signing the AeroFetch artifacts doesn't (and needn't) re-sign them. - Timestamp the signature (electron-builder does by default) so it stays valid after the cert expires. - Signing does **not** replace the smoke test — see [SMOKE-TEST.md](SMOKE-TEST.md).