diff --git a/docs/images/gatekeeper.png b/docs/images/gatekeeper.png index 22567135b7da..04b878ba66ac 100644 Binary files a/docs/images/gatekeeper.png and b/docs/images/gatekeeper.png differ diff --git a/docs/tutorial/code-signing.md b/docs/tutorial/code-signing.md index 49178a1eaecc..deede6771ad4 100644 --- a/docs/tutorial/code-signing.md +++ b/docs/tutorial/code-signing.md @@ -5,34 +5,25 @@ slug: code-signing hide_title: false --- -Code signing is a security technology that you use to certify that an app was -created by you. You should sign your application so it does not trigger any -operating system security checks. +Code signing is a security technology to certify that an app was created by you. +You should sign your application so it does not trigger any operating system +security warnings. -On macOS, the system can detect any change to the app, whether the change is -introduced accidentally or by malicious code. +![macOS Sonoma Gatekeeper warning: The app is damaged](../images/gatekeeper.png) -On Windows, the system assigns a trust level to your code signing certificate -which if you don't have, or if your trust level is low, will cause security -dialogs to appear when users start using your application. Trust level builds -over time so it's better to start code signing as early as possible. - -While it is possible to distribute unsigned apps, it is not recommended. Both -Windows and macOS will, by default, prevent either the download or the execution -of unsigned applications. Starting with macOS Catalina (version 10.15), users -have to go through multiple manual steps to open unsigned applications. - -![macOS Catalina Gatekeeper warning: The app cannot be opened because the developer cannot be verified](../images/gatekeeper.png) - -As you can see, users get two options: Move the app straight to the trash or -cancel running it. You don't want your users to see that dialog. +Both Windows and macOS prevent users from running unsigned applications. It is +possible to distribute applications without codesigning them - but in order to +run them, users need to go through multiple advanced and manual steps to run +them. If you are building an Electron app that you intend to package and distribute, -it should be code signed. +it should be code signed. The Electron ecosystem tooling makes codesigning your +apps straightforward - this documentation explains how sign your apps on both +Windows and macOS. ## Signing & notarizing macOS builds -Properly preparing macOS applications for release requires two steps. First, the +Preparing macOS applications for release requires two steps: First, the app needs to be code signed. Then, the app needs to be uploaded to Apple for a process called **notarization**, where automated systems will further verify that your app isn't doing anything to endanger its users. @@ -65,7 +56,9 @@ are likely using [`@electron/packager`][], which includes [`@electron/osx-sign`] [`@electron/notarize`][]. If you're using Packager's API, you can pass [in configuration that both signs -and notarizes your application](https://electron.github.io/packager/main/interfaces/electronpackager.options.html). +and notarizes your application](https://electron.github.io/packager/main/modules.html). +If the example below does not meet your needs, please see [`@electron/osx-sign`][] and +[`@electron/notarize`][] for the many possible configuration options. ```js @ts-nocheck const packager = require('@electron/packager') @@ -86,35 +79,81 @@ See the [Mac App Store Guide][]. ## Signing Windows builds -Before signing Windows builds, you must do the following: +Before you can code sign your application, you need to acquire a code signing +certificate. Unlike Apple, Microsoft allows developers to purchase those +certificates on the open market. They are usually sold by the same companies +also offering HTTPS certificates. Prices vary, so it may be worth your time to +shop around. Popular resellers include: -1. Get a Windows Authenticode code signing certificate (requires an annual fee) -2. Install Visual Studio to get the signing utility (the free [Community - Edition](https://visualstudio.microsoft.com/vs/community/) is enough) +- [Certum EV code signing certificate](https://shop.certum.eu/data-safety/code-signing-certificates/certum-ev-code-sigining.html) +- [DigiCert EV code signing certificate](https://www.digicert.com/signing/code-signing-certificates) +- [Entrust EV code signing certificate](https://www.entrustdatacard.com/products/digital-signing-certificates/code-signing-certificates) +- [GlobalSign EV code signing certificate](https://www.globalsign.com/en/code-signing-certificate/ev-code-signing-certificates) +- [IdenTrust EV code signing certificate](https://www.identrust.com/digital-certificates/trustid-ev-code-signing) +- [Sectigo (formerly Comodo) EV code signing certificate](https://sectigo.com/ssl-certificates-tls/code-signing) +- [SSL.com EV code signing certificate](https://www.ssl.com/certificates/ev-code-signing/) -You can get a code signing certificate from a lot of resellers. Prices vary, so -it may be worth your time to shop around. Popular resellers include: +It is important to call out that since June 2023, Microsoft requires software to +be signed with an "extended validation" certificate, also called an "EV code signing +certificate". In the past, developers could sign software with a simpler and cheaper +certificate called "authenticode code signing certificate" or "software-based OV certificate". +These simpler certificates no longer provide benefits: Windows will treat your app as +completely unsigned and display the equivalent warning dialogs. -- [digicert](https://www.digicert.com/dc/code-signing/microsoft-authenticode.htm) -- [Sectigo](https://sectigo.com/ssl-certificates-tls/code-signing) -- Amongst others, please shop around to find one that suits your needs! 😄 +The new EV certificates are required to be stored on a hardware storage module +compliant with FIPS 140 Level 2, Common Criteria EAL 4+ or equivalent. In other words, +the certificate cannot be simply downloaded onto a CI infrastructure. In practice, +those storage modules look like fancy USB thumb drives. -:::caution Keep your certificate password private -Your certificate password should be a **secret**. Do not share it publicly or -commit it to your source code. -::: +Many certificate providers now offer "cloud-based signing" - the entire signing hardware +is in their data center and you can use it to remotely sign code. This approach is +popular with Electron maintainers since it makes signing your applications in CI (like +GitHub Actions, CircleCI, etc) relatively easy. + +At the time of writing, Electron's own apps use [DigiCert KeyLocker](https://docs.digicert.com/en/digicert-keylocker.html), but any provider that provides a command line tool for +signing files will be compatible with Electron's tooling. + +All tools in the Electron ecosystem use [`@electron/windows-sign`][] and typically +expose configuration options through a `windowsSign` property. You can either use it +to sign files directly - or use the same `windowsSign` configuration across Electron +Forge, [`@electron/packager`][], [`electron-winstaller`][], and [`electron-wix-msi`][]. ### Using Electron Forge -Electron Forge is the recommended way to sign your `Squirrel.Windows` and `WiX MSI` installers. Detailed instructions on how to configure your application can be found in the [Electron Forge Code Signing Tutorial](https://www.electronforge.io/guides/code-signing/code-signing-macos). +Electron Forge is the recommended way to sign your app as well as your `Squirrel.Windows` +and `WiX MSI` installers. Detailed instructions on how to configure your application can +be found in the [Electron Forge Code Signing Tutorial](https://www.electronforge.io/guides/code-signing/code-signing-windows). + +### Using Electron Packager + +If you're not using an integrated build pipeline like Forge, you +are likely using [`@electron/packager`][], which includes [`@electron/windows-sign`][]. + +If you're using Packager's API, you can pass [in configuration that signs +your application](https://electron.github.io/packager/main/modules.html). If the +example below does not meet your needs, please see [`@electron/windows-sign`][] +for the many possible configuration options. + +```js @ts-nocheck +const packager = require('@electron/packager') + +packager({ + dir: '/path/to/my/app', + windowsSign: { + signWithParams: '--my=custom --parameters', + // If signtool.exe does not work for you, customize! + signToolPath: 'C:\\Path\\To\\my-custom-tool.exe' + } +}) +``` ### Using electron-winstaller (Squirrel.Windows) [`electron-winstaller`][] is a package that can generate Squirrel.Windows installers for your Electron app. This is the tool used under the hood by Electron Forge's -[Squirrel.Windows Maker][maker-squirrel]. If you're not using Electron Forge and want to use -`electron-winstaller` directly, use the `certificateFile` and `certificatePassword` configuration -options when creating your installer. +[Squirrel.Windows Maker][maker-squirrel]. Just like `@electron/packager`, it uses +[`@electron/windows-sign`][] under the hood and supports the same `windowsSign` +options. ```js {10-11} @ts-nocheck const electronInstaller = require('electron-winstaller') @@ -126,8 +165,11 @@ try { outputDirectory: '/tmp/build/installer64', authors: 'My App Inc.', exe: 'myapp.exe', - certificateFile: './cert.pfx', - certificatePassword: 'this-is-a-secret' + windowsSign: { + signWithParams: '--my=custom --parameters', + // If signtool.exe does not work for you, customize! + signToolPath: 'C:\\Path\\To\\my-custom-tool.exe' + } }) console.log('It worked!') } catch (e) { @@ -141,10 +183,8 @@ For full configuration options, check out the [`electron-winstaller`][] reposito [`electron-wix-msi`][] is a package that can generate MSI installers for your Electron app. This is the tool used under the hood by Electron Forge's [MSI Maker][maker-msi]. - -If you're not using Electron Forge and want to use `electron-wix-msi` directly, use the -`certificateFile` and `certificatePassword` configuration options -or pass in parameters directly to [SignTool.exe][] with the `signWithParams` option. +Just like `@electron/packager`, it uses [`@electron/windows-sign`][] under the hood +and supports the same `windowsSign` options. ```js {12-13} @ts-nocheck import { MSICreator } from 'electron-wix-msi' @@ -158,8 +198,11 @@ const msiCreator = new MSICreator({ manufacturer: 'Kitten Technologies', version: '1.1.2', outputDirectory: '/path/to/output/folder', - certificateFile: './cert.pfx', - certificatePassword: 'this-is-a-secret' + windowsSign: { + signWithParams: '--my=custom --parameters', + // If signtool.exe does not work for you, customize! + signToolPath: 'C:\\Path\\To\\my-custom-tool.exe' + } }) // Step 2: Create a .wxs template file @@ -192,6 +235,7 @@ See the [Windows Store Guide][]. [`@electron/osx-sign`]: https://github.com/electron/osx-sign [`@electron/packager`]: https://github.com/electron/packager [`@electron/notarize`]: https://github.com/electron/notarize +[`@electron/windows-sign`]: https://github.com/electron/windows-sign [`electron-winstaller`]: https://github.com/electron/windows-installer [`electron-wix-msi`]: https://github.com/electron-userland/electron-wix-msi [xcode]: https://developer.apple.com/xcode @@ -200,4 +244,3 @@ See the [Windows Store Guide][]. [windows store guide]: ./windows-store-guide.md [maker-squirrel]: https://www.electronforge.io/config/makers/squirrel.windows [maker-msi]: https://www.electronforge.io/config/makers/wix-msi -[signtool.exe]: https://learn.microsoft.com/en-us/dotnet/framework/tools/signtool-exe