Files
AeroFetch/docs/SIGNING.md
T
debont80 24c4c807a3 feat: Phase P reliability (YouTube extractor-args plumbing, signing + smoke-test docs)
- YouTube reliability: Settings.youtubePlayerClient + youtubePoToken ->
  one --extractor-args "youtube:player_client=...;po_token=..." group
  (accessArgs, unit-tested); advanced fields in Settings -> Network.
  Automatic WebView PO-token minting deferred (documented).
- docs/SMOKE-TEST.md: release-gate checklist for all shipped-but-untested
  OS wiring (cookies window, protocol/Send-to, scheduled sync, aria2c, proxy,
  tray/taskbar/pause-resume/terminal) — needs a human to run.
- docs/SIGNING.md: code-signing guide (CSC_LINK/CSC_KEY_PASSWORD, OV/EV,
  CI, HSM hook, verification). Build is signing-ready; needs a cert.
- i18n remains deferred (not faked).

typecheck + test (195) + build all clean. Roadmap: Phase P code shipped.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 11:25:57 -04:00

3.1 KiB

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:

# PowerShell
$env:CSC_LINK = "C:\path\to\codesign.pfx"   # or a base64 string of the .pfx
$env:CSC_KEY_PASSWORD = "<pfx password>"
npm run build:win
# 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 <ver>.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:

- 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

Get-AuthenticodeSignature ".\dist\AeroFetch Setup <ver>.exe" | Format-List
# Status should be 'Valid'; SignerCertificate should be your cert.
signtool verify /pa /v ".\dist\AeroFetch Setup <ver>.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.