Electron Forge
  • Getting Started
  • Importing an Existing Project
  • CLI
  • Core Concepts
    • Why Electron Forge?
    • Build Lifecycle
  • Configuration
    • Configuration Overview
    • TypeScript Setup
    • Plugins
      • Webpack Plugin
      • Vite Plugin
      • Electronegativity Plugin
      • Auto Unpack Native Modules Plugin
      • Local Electron Plugin
      • Fuses Plugin
    • Makers
      • AppX
      • deb
      • DMG
      • Flatpak
      • pkg
      • RPM
      • Snapcraft
      • Squirrel.Windows
      • WiX MSI
      • ZIP
    • Publishers
      • Bitbucket
      • Electron Release Server
      • GitHub
      • Google Cloud Storage
      • Nucleus
      • S3
      • Snapcraft
    • Hooks
  • Built-in Templates
    • Webpack
    • Webpack + Typescript
    • Vite
    • Vite + TypeScript
  • Guides
    • Code Signing
      • Signing a Windows app
      • Signing a macOS app
    • Custom App Icons
    • Framework Integration
      • React
      • React with TypeScript
      • Vue 3
    • Developing with WSL
  • Advanced
    • Auto Update
    • Debugging
    • Extending Electron Forge
      • Writing Plugins
      • Writing Templates
      • Writing Makers
      • Writing Publishers
    • API Docs
Powered by GitBook
On this page
  • Prerequisites
  • Installing Xcode
  • Obtaining signing certificates
  • Configuring Forge
  • osxSign options
  • osxNotarize options
  • Example configuration

Was this helpful?

Edit on GitHub
  1. Guides
  2. Code Signing

Signing a macOS app

Code signing is a security technology that you use to certify that an app was created by you.

PreviousSigning a Windows appNextCustom App Icons

Last updated 6 months ago

Was this helpful?

On macOS, there are two layers of security technology for application distribution: code signing and notarization.

  • Code Signing is the act of certifying the identity of the app's author and ensuring it was not tampered with before distribution.

  • Notarization is an extra verification step where the app is sent to Apple servers for an automated malware scan.

From macOS 10.15 (Catalina) onwards, your application needs to be both code signed and notarized to run on a user's machine without disabling additional operating system security checks.

The exception is for Mac App Store (MAS) apps, where notarization is not required because the MAS submission process involves a similar automated check.

Prerequisites

Installing Xcode

is Apple's integrated development environment (IDE) for development on macOS, iOS, and other platforms.

Although Electron does not integrate tightly with the IDE itself, Xcode is a helpful tool for installing code signing certificates (see next section) and is required for notarization.

Obtaining signing certificates

Code signing certificates for macOS apps can only be obtained through Apple by purchasing a membership to the .

To sign Electron apps, you may require two separate certificates:

  • The Developer ID Installer certificate is for apps distributed to the Mac App Store.

  • The Developer ID Application certificate is for apps distributed outside the Mac App Store.

Once you have an Apple Developer Program membership, you first need to install them onto your machine. We recommend .

Verifying your certificate is installed

Once you have installed your certificate, you can check available code signing certificates in your terminal using the following shell command:

security find-identity -p codesigning -v

Configuring Forge

In Electron Forge, macOS apps are signed and notarized at the Package step by the electron-packager library. There is a separate option within your Forge packagerConfig for each one of these settings.

osxSign options

To enable code signing on macOS, ensure that packagerConfig.osxSign exists in your Forge configuration.

forge.config.js
module.exports = {
  packagerConfig: {
    osxSign: {} // object must exist even if empty
  }
};

The osxSign config comes with defaults that work out of the box in most cases, so we recommend you start with an empty configuration object.

Customizing entitlements

A common use case for modifying the default osxSign configuration is to customize its entitlements. In macOS, entitlements are privileges that grant apps certain capabilities (e.g. access to the camera, microphone, or USB devices). These are stored within the code signature in an app's executable file.

forge.config.js
module.exports = {
  // ...
  packagerConfig: {
    // ...
    osxSign: {
      optionsForFile: (filePath) => {
        // Here, we keep it simple and return a single entitlements.plist file.
        // You can use this callback to map different sets of entitlements
        // to specific files in your packaged app.
        return {
          entitlements: 'path/to/entitlements.plist'
        };
      }
    }
  }
  // ...
};

For further reading on entitlements, see the following pages in Apple developer documentation:

osxNotarize options

The notarytool command has three authentication options, which are detailed below. Note that you will want to use a forge.config.js configuration so that you can load environment variables into your Forge config.

Keep your authentication details private

Option 1: Using an app-specific password

There are two mandatory fields for osxNotarize if you are using this strategy:

Field
Type
Description

appleId

string

Apple ID associated with your Apple Developer account

appleIdPassword

string

App-specific password

teamId

string

forge.config.js
module.exports = {
  // ...
  packagerConfig: {
    // ...
    osxNotarize: {
      appleId: process.env.APPLE_ID,
      appleIdPassword: process.env.APPLE_PASSWORD,
      teamId: process.env.APPLE_TEAM_ID
    }
  }
  // ...
};

Despite the name, appleIdPassword is not the password for your Apple ID account.

Option 2: Using an App Store Connect API key

There are three mandatory fields for osxNotarize if you are using this strategy:

Field
Type
Description

appleApiKey

string

Filesystem path string to your API key file.

appleApiKeyId

string

10-character alphanumeric ID string. In the previous AuthKey_ABCD123456.p8 example, this would be ABCD123456.

appleApiIssuer

string

UUID that identifies the API key issuer. You will find this ID in the "Keys" tab where you generated your API key.

forge.config.js
module.exports = {
  // ...
  packagerConfig: {
    // ...
    osxNotarize: {
      appleApiKey: process.env.APPLE_API_KEY,
      appleApiKeyId: process.env.APPLE_API_KEY_ID,
      appleApiIssuer: process.env.APPLE_API_ISSUER
    }
  }
  // ...
};

Option 3: Using a keychain

You can do this directly in your terminal via the notarytool store-credentials command. For usage information, you can refer to the man page for notarytool:

man notarytool

There are two available fields for osxNotarize if you are using this strategy:

Field
Type
Description

keychainProfile

string

Name of the keychain profile containing your notarization credentials.

keychain (optional)

string

Name of (or path to) the keychain containing the profile with your credentials.

Note that if you use notarytool store-credentials, the keychain parameter can be auto-detected.

forge.config.js
module.exports = {
  // ...
  packagerConfig: {
    // ...
    osxNotarize: {
      keychainProfile: 'my-keychain-profile'
    }
  }
  // ...
};

Example configuration

Below is a minimal Forge configuration for osxSign and osxNotarize.

forge.config.js
module.exports = {
  packagerConfig: {
    osxSign: {},
    osxNotarize: {
      appleId: process.env.APPLE_ID,
      appleIdPassword: process.env.APPLE_PASSWORD,
      teamId: process.env.APPLE_TEAM_ID
    }
  }
};

Under the hood, Electron Forge uses the tool to sign your macOS application.

For a full list of configuration options, see the type in the Forge API docs. For more detailed information on how to configure these options, see the .

By default, the @electron/osx-sign tool comes with a set of entitlements that should work on both MAS or direct distribution targets. See the complete set of default entitlement files .

Under the hood, Electron Forge uses the tool to notarize your macOS application.

You should never store authentication info in plaintext in your configuration. In the examples below, credentials are stored as environment variables and accessed via the Node.js object.

You can generate an from Apple to provide your credentials to notarytool. This password will need to be regenerated if you change your Apple ID password.

The Apple Team ID you want to notarize under. You can find Team IDs for team you belong to by going to

You can generate an App Store Connect API key to authenticate notarytool by going to the and using the "Team Keys" tab. This API key will look something like AuthKey_ABCD123456.p8 and can only be downloaded once.

Instead of providing environment variables to the Forge config passed to notarytool, you can choose to use a macOS containing either set of credentials (either Option 1 or Option 2 above).

Xcode
Apple Developer Program
loading them through Xcode
@electron/osx-sign
OsxSignOptions
@electron/osx-sign documentation
on GitHub
Entitlements
Hardened Runtime
@electron/notarize
process.env
app-specific password
App Store Connect access page
keychain
https://developer.apple.com/account/#/membership