MacOS: How to code sign and notarize an electron app in 2022?

June 4, 2022

I started to build a desktop app using Electron for my task automation project called Rocketride

I thought code signing and notarization will be fairly easy to do ... I was wrong :) At the end it was the most complicated, painful part of the process. The tutorials and examples are mostly outdated (mostly 2019).

This tutorial described the steps I did. I hope you find it useful.

Why do you need to sign and notarize your Mac App?

Simple: your users won't be able to install your app. Gatekeeper will prevent it.

What steps did I do?

  1. Enroll to the Apple Developer program
  2. Create a Developer ID Application Certificate
  3. Create a Developer ID Installer Certificate
  4. Download & install XCode
  5. Prepare your Electron project for notarization
  6. Build your Electron App
  7. Notarize your Electron app
  8. Create a DMG file

Enroll to the Apple developer program

1. Create an account: Apple Developer Program
I used a dedicated email address for the developer account. I didn't want to mix it with my normal account I use daily.

2. Follow the steps on this portal and buy the yearly license for $99 or €99. It takes Apple a few hours, sometimes some days to process your documents

Apple Developer Portal

3. Store the Team ID somewhere. You'll need it when you sign the Electron app

Copy the teamID somewhere to use it later

Create a Developer ID Application Certificate

This Developer ID App certificate will be used to code sign your application.

1. Open your Keychain Access app

2. Open the Certificate Assistant

This is the menu item you need

3. Enter the email address of your Apple Developer account to the "User Email Address" input field

4. Leave the CA Email Address empty

Fill out the form

5. Select "Save to disk" and then press Continue

6. Save the certificate to your Hard drive. This is a Certificate Signing Request (CSR) certificate and you'll need this to create a Developer ID Application certificate.

7. Go to the Apple Developer Portal and click on the "Certificates, IDs & Profiles" menu item

8. Click on Blue plus icon to create a new certificate

Certificates overview

9. Select the Developer ID application certificate from the list

Select this certificate type

10. Select "G2 Sub-CA (Xcode 11.4.1 or later)" and upload the CSR file you saved in step 6.

Upload the CSR file

11. Click continue and download the certificate file to your HDD

12. Select "System" from the left menu of the Keychain Access app

Select "System" from the left menu

13. Open a Finder and double-click on the Developer ID Application certificate. It will be shown in your Keychain

Create a Developer ID Installer Certificate

Repeat the steps you did for Developer ID Application Certificate. The only difference is that you need to choose Developer ID Installer certificate from the list.

Select "Developer ID Installer Certificate"

Download & install XCode

You can download it from the App Store or from here

XCode in appstore

Prepare your Electron project for notarization

1. Install Electron Builder. github repo

2. I have these in my package.json's script section

"scripts": {
  "start": "electron .",
  "pack": "build --dir",
  "dist": "electron-builder"
},
        

3. Add these to your build section. Of course use a different appId.
HardenedRuntime, gatekeeperAssess and the entitlements are required for the successful Notarization process.
The official Apple Notarization page

"build": {
  "appId": "rocketride.io",
  "mac": {
    "hardenedRuntime": true,
    "entitlements": "build/entitlements.mac.plist",
    "entitlementsInherit": "build/entitlements.mac.plist",
    "gatekeeperAssess": false,
    "category": "public.app-category.developer-tools"
  }
}
        

4. Create a build folder in your project's root directory.

5. Create a file called entitlements.mac.plist: Download the file here

Build your Electron App

1. Run the following line in the Terminal

npm run dist

If you did the previous steps right then electron builder will build your app and sign it with the Developer ID Application Certificate.

The .app file will be placed to /dist/mac folder

Notarize your Electron app

1. Sign in to appleid.apple.com to get an App-Specific password

2. Click on App-Specific passwords

Apple ID portal

3. Click on Plus icon and follow the instructions to get an App specific password.

Apple ID portal

4. Copy the App specific password, you'll need it in the next step.
Be aware: You will only be shown the password when you create it.

5. Go to the dist/mac folder in Terminal

6. Run the following line in Terminal to store the App specific password to your keychain

The profile name is important here: this is how you'll reference the keychain entry. In my case it is rocketride.io

$ xcrun notarytool store-credentials --apple-id "name@example.com" --team-id "ABCD123456"

This process stores your credentials securely in the Keychain. You reference these credentials later using a profile name.

Profile name: rocketride.io
Password for name@example.com:
Validating your credentials...
Success. Credentials validated.
Credentials saved to Keychain.
            To use them, specify `--keychain-profile "rocketride.io"`

the value for --apple-id is the email address you use for your Apple Developer Account.
the value for --team-id is the Team ID from your Apple Developer program (See the first step of this tutorial).

7. Create a ZIP from the .app file -> for example: yourapp.zip

xcrun notarytool submit yourapp.zip --keychain-profile "rocketride.io" --wait

In the --keychain-profile use the profile name you used in step 6.

This command will upload your app to the Apple servers and the automated notary service will check it. The notarization process take 1-2 mins.
If everything goes well you'll see something like this at the end.

8. You need to attach the notarization info to your app. This is not mandatory, but very useful.

xcrun stapler staple yourapp.app

You can check if your app is properly notarized

$ spctl --assess -vv --type install yourapp.app

youarapp.app: accepted
source=Notarized Developer ID
            origin=Developer ID Application: Andras Szabo (yourTeamId)

Create a DMG file

Download the DMG Canvas app to generate a DMG file.

You should not sign a DMG, because if you sign it you need to notarize it. And that doesn't work on DMG files.