macOS requires code signing and notarization for release
Preparing macOS applications for release requires two steps: first, the app needs to be code signed, and then the app needs to be uploaded to Apple for notarization, where automated systems verify that the app is not doing anything to endanger its users.
macOS code signing requirements: Apple Developer Program, Xcode, and signing certificates
To sign and notarize a macOS app, you must: enroll in the Apple Developer Program (requires an annual fee), download and install Xcode (requires a computer running macOS), and generate, download, and install signing certificates.
Electron Forge includes code signing tools for macOS
Electron Forge is a collection of official Electron tools that uses @electron/packager, @electron/osx-sign, and @electron/notarize under the hood to make signing and notarizing applications straightforward.
Example: Signing and notarizing macOS app with Electron Packager
```js
const packager = require('@electron/packager')
packager({
dir: '/path/to/my/app',
osxSign: {},
osxNotarize: {
appleId: 'felix@felix.fun',
appleIdPassword: 'my-apple-id-password'
}
})
```
This example shows how to configure Electron Packager to both sign and notarize a macOS application using osxSign and osxNotarize options.
safeStorage requires valid code signature on macOS
Without a valid, consistent code signature on macOS, the safeStorage API may behave inconsistently. macOS may be unable to tell that two builds of an unsigned app are "the same app", which can cause the Keychain to prompt the user for permission again after every update.
app.setLoginItemSettings requires proper code signing on macOS
Login items can behave incorrectly (e.g. silently failing to register) when the app is not packaged, code signed, and notarized on macOS.
Cookie encryption fuse requires code signing on macOS
The cookieEncryption fuse uses the same OS-level access to the Keychain as safeStorage, so it has the same code signing requirement on macOS. Without proper code signing, cookie encryption may not work correctly.
autoUpdater requires code signing on macOS
Squirrel.Mac requires the app to be signed for automatic updates to work at all on macOS.
Azure Artifact Signing is Microsoft's modern cloud-based signing service
Azure Artifact Signing (formerly known as Azure Trusted Signing) is Microsoft's modern cloud-based signing service. It is the cheapest option for code signing on Windows and removes SmartScreen warnings. However, it is currently limited to developers in certain countries.
Example: Signing Windows app with jsign for Azure Artifact Signing
```bash
jsign --storetype TRUSTEDSIGNING \
--keystore https://eus.codesigning.azure.net/ \
--storepass $AZURE_ACCESS_TOKEN \
--alias trusted-sign-acct/AppName \
--tsaurl http://timestamp.acs.microsoft.com/ \
--tsmode RFC3161 \
--replace <file>
```
This example shows how to use jsign to sign Windows applications via Azure Artifact Signing from Linux or macOS.
Windows requires EV code signing certificates since June 2023
Since June 2023, Microsoft requires software to be signed with an "extended validation" certificate (EV code signing certificate). Simpler certificates like "authenticode code signing certificate" or "software-based OV certificate" no longer provide benefits—Windows will treat the app as completely unsigned and display warning dialogs.
EV certificates must be stored on FIPS 140 Level 2 hardware
New EV certificates required for Windows code signing must be stored on a hardware storage module compliant with FIPS 140 Level 2, Common Criteria EAL 4+ or equivalent. The certificate cannot simply be downloaded onto CI infrastructure; storage modules typically look like hardware USB drives.
Cloud-based signing enables CI integration for Windows code signing
Many certificate providers now offer "cloud-based signing" where the entire signing hardware is in their data center and can be used to remotely sign code. This approach is popular with Electron maintainers because it makes signing applications in CI (like GitHub Actions, CircleCI) relatively easy.
Electron ecosystem uses @electron/windows-sign for Windows code signing
All tools in the Electron ecosystem use @electron/windows-sign and typically expose configuration options through a windowsSign property. This can be used to sign files directly or apply the same windowsSign configuration across Electron Forge, @electron/packager, electron-winstaller, and electron-wix-msi.
Example: Signing Windows app with Electron Packager
```js
const packager = require('@electron/packager')
packager({
dir: '/path/to/my/app',
windowsSign: {
signWithParams: '--my=custom --parameters',
signToolPath: 'C:\\Path\\To\\my-custom-tool.exe'
}
})
```
This example shows how to configure Electron Packager to sign a Windows application using custom signing parameters and a custom signing tool path.
Example: Signing Windows installer with electron-winstaller
```js
const electronInstaller = require('electron-winstaller')
try {
await electronInstaller.createWindowsInstaller({
appDirectory: '/tmp/build/my-app-64',
outputDirectory: '/tmp/build/installer64',
authors: 'My App Inc.',
exe: 'myapp.exe',
windowsSign: {
signWithParams: '--my=custom --parameters',
signToolPath: 'C:\\Path\\To\\my-custom-tool.exe'
}
})
console.log('It worked!')
} catch (e) {
console.log(`No dice: ${e.message}`)
}
```
This example shows how to use electron-winstaller to create a Squirrel.Windows installer with code signing configuration.
Example: Signing Windows MSI installer with electron-wix-msi
```js
import { MSICreator } from 'electron-wix-msi'
const msiCreator = new MSICreator({
appDirectory: '/path/to/built/app',
description: 'My amazing Kitten simulator',
exe: 'kittens',
name: 'Kittens',
manufacturer: 'Kitten Technologies',
version: '1.1.2',
outputDirectory: '/path/to/output/folder',
windowsSign: {
signWithParams: '--my=custom --parameters',
signToolPath: 'C:\\Path\\To\\my-custom-tool.exe'
}
})
const supportBinaries = await msiCreator.create()
for (const binary of supportBinaries) {
await signFile(binary)
}
await msiCreator.compile()
```
This example shows how to use electron-wix-msi to create a WiX MSI installer with code signing, including signing support binaries.
Popular Windows EV code signing certificate providers
Popular resellers of EV code signing certificates for Windows include: DigiCert, GlobalSign, Sectigo, and SSL.com. Prices vary, so it may be worth shopping around.
Code signing prevents OS security checks
Code signing is a security technology used to certify that an app was created by you. Signing your application prevents it from triggering the security checks of your user's operating system.
Mac App Store submission requirements
To sign Electron apps for Mac App Store, you must install Xcode 11 or above and the @electron/osx-sign npm module. You also need to register an Apple Developer account and join the Apple Developer Program.
Apple Development certificate purpose and limitations
The Apple Development certificate is used to sign apps for development and testing on machines registered with Apple Developer website. Apps signed with this certificate cannot be submitted to Mac App Store.
Apple Distribution certificate purpose
The Apple Distribution certificate is used to sign apps for Mac App Store submission. Apps signed with this certificate cannot run directly; they must be re-signed by Apple after being downloaded from the Mac App Store to run.
Developer ID Application certificate for non-App Store distribution
The Developer ID Application certificate is used to sign apps before distributing them outside the Mac App Store. Unlike Apple Development and Apple Distribution certificates, it does not require App Sandbox and works with both normal and MAS builds of Electron.
Certificate types requiring App Sandbox
Apps signed with Apple Development and Apple Distribution certificates can only run under App Sandbox, so they must use the MAS build of Electron.
Get certificates from Apple using Xcode
Open Xcode Accounts preferences, sign in with your Apple account, select a team, click Manage Certificates, and in the lower-left corner click the Add button (+) to add Apple Development and Apple Distribution certificates.
Provision profile creation for development testing
To test your app on a local machine before Mac App Store submission, you must sign with Apple Development certificate and embed a provisioning profile in the app bundle. Create the provisioning profile on Apple Developer website in the Profiles page, and download it to /path/to/yourapp.provisionprofile.
Register device for provisioning profile
To create a provisioning profile for development, you must register your local machine in the Devices page on Apple Developer website using your machine's Device ID, which can be found in the Hardware page of System Information app.
Sign app for development with @electron/osx-sign
Use signAsync({app: '/path/to/your.app', identity: 'Apple Development', provisioningProfile: '/path/to/your.provisionprofile'}) to sign an app that runs on your development machine.
Sign app for Mac App Store submission with @electron/osx-sign
Use signAsync({app: 'path/to/your.app', identity: 'Apple Distribution'}) to sign an app for Mac App Store submission.
Place provisioning profile without @electron/osx-sign
When signing an app without @electron/osx-sign, place the provisioning profile at YourApp.app/Contents/embedded.provisionprofile.
Custom entitlements per file with @electron/osx-sign
With @electron/osx-sign, you can set custom entitlements per file using the optionsForFile callback that returns an object with an entitlements property specifying the path to the entitlements file based on the file being signed.
Cryptographic algorithms used by Electron
Electron uses the following cryptographic algorithms: AES, HMAC, ECDSA, ECDH, HKDF, PBKDF2, RSA, SHA, Blowfish, CAST, DES, DH, DSA, EC, IDEA, MD2, MD4, MD5, MDC2, RC2, RC4, RC5, and RIPEMD.
Legacy certificate names
Apple has changed certificate names over time. Apple Distribution was formerly 3rd Party Mac Developer Application or Mac App Distribution. Apple Development was formerly Mac Developer or Development.
Code signing is mandatory for auto-update
Code signing is an important part of shipping desktop applications and is mandatory for the auto-update functionality. It is highly recommended that you code sign your Electron app before distributing it to end users.
Code signing prevents untrusted app execution
Code signing is a security technology used to certify that a desktop app was created by a known source. Windows and macOS have their own OS-specific code signing systems that will make it difficult for users to download or launch unsigned applications.
macOS code signing is done at app packaging level
On macOS, code signing is done at the app packaging level using the osxSign and osxNotarize configuration options in forge.config.js.
Windows code signing uses distributable installers
On Windows, distributable installers are signed instead of individual apps. This is configured using maker-squirrel with certificateFile and certificatePassword in forge.config.js.
macOS code signing configuration in forge.config.js
For macOS, configure code signing in forge.config.js under packagerConfig with osxSign: {} and osxNotarize object containing: tool (set to 'notarytool'), appleId (process.env.APPLE_ID), appleIdPassword (process.env.APPLE_PASSWORD), and teamId (process.env.APPLE_TEAM_ID).
Windows code signing configuration in forge.config.js
For Windows, configure code signing in forge.config.js under makers array with maker-squirrel config object containing: certificateFile (path to .pfx certificate file) and certificatePassword (process.env.CERTIFICATE_PASSWORD).