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
      • 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
  • Using traditional certificates
  • Prerequisites
  • Configuring Electron Forge
  • Using Azure Trusted Signing
  • Prerequisites
  • Configuring Electron Forge

Was this helpful?

Edit on
  1. Guides
  2. Code Signing

Signing a Windows app

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

PreviousCode SigningNextSigning a macOS app

Last updated 1 month ago

Was this helpful?

Using traditional certificates

Starting June 1, 2023 at 00:00 UTC, private keys for code signing certificates need to be stored on a hardware storage module compliant with FIPS 140 Level 2, Common Criteria EAL 4+ or equivalent. In practice, this means that software-based OV certificates used in the steps below will no longer be available for purchase. For instructions on how to sign applications with newer token-based certificates, consult your Certificate Authority's documentation.

Prerequisites

Installing Visual Studio

On Windows, apps are signed using, which is included in Visual Studio. Install Visual Studio to get the signing utility (the freeis enough).

Acquiring a certificate

You can get acode signing certificate from many vendors. Prices vary, so it may be worth your time to shop around. Popular vendors include:

  • Amongst others, please shop around to find one that suits your needs! 😄

Keep your certificate password private

Your certificate password should be a secret. Do not share it publicly or commit it to your source code.

Configuring Electron Forge

On Windows, Electron apps are signed on the installer level at the Make step.

For example, if you are creating a Squirrel.Windows installer:

forge.config.js
module.exports = {
  packagerConfig: {},
  makers: [
    {
      name: '@electron-forge/maker-squirrel',
      config: {
        certificateFile: './cert.pfx',
        certificatePassword: process.env.CERTIFICATE_PASSWORD
      }
    }
  ]
};

Using Azure Trusted Signing

Prerequisites

Configuring Electron Forge

Installing npm dependencies

In your project directory, do the following:

  1. Install the dotenv-cli package: npm i -D dotenv-cli

  2. Update @electron/windows-sign to version 1.2.0 or later: npm update @electron/windows-sign

Creating the .env.trustedsigning file

Create a file .env.trustedsigning in your project root with the following content:

.env.trustedsigning
AZURE_CLIENT_ID='xxx'
AZURE_CLIENT_SECRET='xxx'
AZURE_TENANT_ID='xxx'
AZURE_METADATA_JSON='C:\path\to\metadata.json'
AZURE_CODE_SIGNING_DLIB='C:\path\to\bin\x64\Azure.CodeSigning.Dlib.dll'
SIGNTOOL_PATH='C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x64\signtool.exe'

Fill in the credentials for your Azure App Registration user into the first three variables.

Adjust the other variables to be the absolute paths to the metadata.json, Azure.CodeSigning.Dlib.dll and signtool.exe files that you created or installed as part of the prerequisites.

Adjusting your .gitignore

Add .env.trustedsigning to your .gitignore file. You should never commit login credentials to version control.

In addition, add electron-windows-sign.log to .gitignore. This file will be created automatically during the signing process.

.gitignore
.env.trustedsigning
electron-windows-sign.log

Creating the windowsSign.ts file

Create a file windowsSign.ts in your project root with the following content:

windowsSign.ts
import type { WindowsSignOptions } from "@electron/packager";
import type { HASHES } from "@electron/windows-sign/dist/esm/types";

export const windowsSign: WindowsSignOptions = {
  ...(process.env.SIGNTOOL_PATH
    ? { signToolPath: process.env.SIGNTOOL_PATH }
    : {}),
  signWithParams: `/v /debug /dlib ${process.env.AZURE_CODE_SIGNING_DLIB} /dmdf ${process.env.AZURE_METADATA_JSON}`,
  timestampServer: "http://timestamp.acs.microsoft.com",
  hashes: ["sha256" as HASHES],
};

If you are using JavaScript for your configuration instead of TypeScript, adjust the file accordingly. Name the file windowsSign.js and remove the type information.

Some notes:

We specify the /v and /debug parameters even though they aren't technically required. This ensures that warnings are logged if timestamping fails.

Do not use the debug parameter on the WindowsSignOptions. Similarly, do not enable the DEBUG environment variable for electron-windows-sign. (If you do either of them, the debug npm package will log all debug messages to stderr. An executable in @electron/windows-sign will interpret the existence of messages printed to stderr as a signing failure. Then your build will fail.)

Adjusting your forge.config.ts

In your forge.config.ts, add the following:

forge.config.ts
// Add import:
import { windowsSign } from "./windowsSign";

const config: ForgeConfig = {
  packagerConfig: {
    // Add this line:
    windowsSign,
  },
  makers: [
    new MakerSquirrel({
      // Add the following two lines:
      // @ts-expect-error - incorrect types exported by MakerSquirrel
      windowsSign,
    }),
  ],
};

Updating your npm scripts

When you call scripts such as electron-forge make or electron-forge publish, you will now have to prefix them with dotenv -e .env.trustedsigning --. This loads the environment variables from the .env.trustedsigning file.

For example, your npm scripts in your package.json might then look like this:

package.json
{
  "scripts": {
    "make": "dotenv -e .env.trustedsigning -- electron-forge make",
    "publish": "dotenv -e .env.trustedsigning -- electron-forge publish"
  }
}

Once you have a Personal Information Exchange (.pfx) file for your certificate, you can signandinstallers in Electron Forge with the certificateFile and certificatePassword fields in their respective configuration objects.

is Microsoft's modern cloud-based alternative to EV certificates. It is the cheapest option for code signing on Windows, and it gets rid of SmartScreen warnings.

As of November 2024, Azure Trusted Signing is available to organizations with 3+ years of verifiable business history and to individuals. Microsoft isto organizations with a shorter history, too. If you're reading this at a later point, it could make sense to check.

First, create an Azure account and set up Azure Trusted Signing in your account as described.

Then install the dependencies for local code signing as described. Also create the required metadata.json file in an arbitrary location on your computer.

Ensure that none of the paths have spaces in them. Otherwise, signing will fail. (@electron/windows-sign issuecurrently prevents quoting of paths with spaces.)

Sign Tool
Community Edition
Windows Authenticode
digicert
Sectigo
Squirrel.Windows
MSI
Azure Trusted Signing
looking to make the program available
here
here
#45