Code Signing — Authenticode Signing of Distributables
Runbook for Authenticode-signing the project's own binaries (FindMyFiles.exe and others) in the
distribution zip with SSL.com eSigner (cloud HSM signing). For the decision rationale and rejected
alternatives, see ADR-0020.
Current state
The signing step in .github/workflows/release.yml is wired up but dormant. Signing is non-blocking:
until the repository Secrets (ES_USERNAME / CREDENTIAL_ID) are in place, cutting a tag still completes,
leaving the binaries unsigned and emitting a ::warning::.
Signing activates automatically from the next tag after you obtain a certificate and register the 4 Secrets below.
No other CI changes are needed.
Only the project's own PE files are signed — FindMyFiles.exe (the executable the user launches = the main
target of SmartScreen evaluation), fmf.exe, fmf-service.exe, fmf_engine.dll. The bundled .NET / WindowsAppSDK
runtime DLLs are already Microsoft-signed and are not re-signed (to avoid wasting the signing quota and signing
others' copyrighted works).
Background (why this setup)
- An individual residing in Japan is not eligible for the individual tier of Azure Artifact Signing (formerly Trusted Signing) (US/CA/EU/UK only).
- EV signing no longer grants immediate SmartScreen trust (Microsoft changed this in March 2024). This app ships no kernel driver, so taking EV brings almost no practical benefit. Therefore individual-name IV (Individual Validation) is sufficient.
- SmartScreen is reputation-based. Even when signed, a warning may appear on first run and disappears as download history accumulates. The immediate effect of signing is that "unknown publisher" disappears and your name appears in the properties.
Activation procedure (when you want a certificate)
A. Obtain the certificate (SSL.com)
- Create an account at SSL.com.
- Purchase a Code Signing certificate. Choose Individual Validation (IV) with eSigner (cloud signing)
support (the cloud version, not the USB token version). Expect roughly $130–250 per year.
- Only if you want the EV title, you may choose Sole Proprietor EV (no corporate registration required). No changes to this repository's CI (same Action, same 4 Secrets). But SmartScreen behavior is the same as IV.
B. Identity verification (IV validation)
- Government-issued ID + identity verification (documents/video). No corporate registration required. There is a track record of Japanese individuals / sole proprietors obtaining it.
C. Configure eSigner for automated signing
- In the SSL.com dashboard:
- Note the Credential ID of the signing certificate.
- Issue and note the TOTP (2FA) secret for automated signing (a Base32 string).
- The account username / password.
D. Register 4 GitHub Secrets
-
In the repository → Settings → Secrets and variables → Actions → New repository secret:
Secret name Value ES_USERNAMESSL.com username ES_PASSWORDSSL.com password CREDENTIAL_IDCredential ID of the signing certificate ES_TOTP_SECRETTOTP secret for eSigner automated signing (Base32) → On the next
vX.Y.Ztag (orreleaseviaworkflow_dispatch),HAVE_SIGNINGbecomestrueand signing runs.
E. Verification
- Dry run (possible right now, even before obtaining a certificate): with Secrets unset, run Actions → release
via
workflow_dispatch→ confirm that the signing step is skipped, a::warning::is emitted, and the zip / checksum / Release creation complete without failure (= the dormant wiring does not break the pipeline). - Real signing (after registering Secrets): cut a test tag (e.g.
v0.0.1-rc1) and run. Confirm that "Sign staged binaries" runs and "Verify signatures" turns green with all 4 files showingsigned: ... - CN=<your name>. - Local confirmation: extract the Release zip and on Windows:
In the properties ofsigntool verify /pa /v build\dist\FindMyFiles\FindMyFiles.exe # → Successfully verified Get-AuthenticodeSignature build\dist\FindMyFiles\FindMyFiles.exe # → Status: ValidFindMyFiles.exe→ "Digital Signatures" tab, your name and a timestamp appear.
Renewal (handling expiry)
- The validity period of a publicly trusted code signing certificate is, per CA/Browser Forum rules, at most ~460 days (about 15 months). Renew at SSL.com before expiry.
- Only if the Credential ID / TOTP change on renewal, update the corresponding Secret.
Troubleshooting
- Verify signatures fails:
batch_signmay have written the signed files to a separate folder instead ofoverride. Check the output location in the Action log and, if needed, specifyoutput_pathin the signing step ofrelease.ymlso the copy source for "Copy signed binaries back" matches it. Get-AuthenticodeSignaturereturnsUnknownError: the public trust chain is unresolved. Check details withsigntool verify /pa.- A SmartScreen warning still appears on first launch: expected (reputation is shallow). It disappears as downloads accumulate. Same with EV.
Related
- ADR-0020 — Code Signing Provider Selection
- SECURITY.md
- Wiring itself:
.github/workflows/release.yml