Skip to main content

Code Signing for Windows

Windows code signing is supported and runs automatically once you configure a signing method — or simply provide signing credentials through environment variables. electron-builder signs every executable and installer it produces so that Windows SmartScreen and your auto-updater can verify your app's publisher and confirm it hasn't been tampered with.

Dual signing

By default each binary is dual-signed with both SHA-1 and SHA-256 (signingHashAlgorithms: ["sha1", "sha256"]) so it validates on legacy as well as modern Windows. A few targets are fixed: .msi is single-signed and AppX/MSIX is SHA-256 only.

Choosing a signing method

electron-builder offers several signing backends, selected by the type field of win.sign (detailed in the table below). Pick based on where your private key lives and which OS your build runs on:

  • Certificate file or Windows store (signtool, the default) — a .pfx/.p12 file or a certificate already in the Windows certificate store. Signs with Microsoft signtool.exe on Windows and osslsigncode on macOS/Linux.
  • Hardware Security Module / FIPS token (hsm) — the key stays in hardware, accessed through a Windows cryptographic service provider. Windows only.
  • PKCS#11 hardware token (pkcs11) — a smart card, USB HSM, or network token reached through a PKCS#11 module. Runs on macOS/Linux via osslsigncode.
  • Azure Trusted Signing (azure) — Microsoft's cloud signing service; no local key to manage. Works on any OS.

OV vs. EV certificates

For file- or store-based signing you need a Windows code signing certificate from a CA (DigiCert, Sectigo, SSL.com, …). They come in two grades:

  • OV (Organization Validation) — the common, lower-cost option. New publishers see a SmartScreen "unknown publisher" warning during install that fades as your download reputation grows. OV certificates export to a .pfx, so they work in CI with the signtool method.
  • EV (Extended Validation) — earns SmartScreen reputation immediately, but its private key is bound to a hardware token and cannot be exported to a file. Identify an EV certificate by certificateSubjectName or certificateSha1 rather than a file path, and sign with the hsm (Windows) or pkcs11 (macOS/Linux) method — or switch to azure to avoid managing hardware at all.

Both grades work with auto-update.

Signing without a Windows machine

You don't need Windows to sign a Windows app. The default signtool method signs file-based certificates with osslsigncode on macOS/Linux, and the pkcs11 and azure methods are designed for non-Windows CI. See also Code Signing Windows Apps on Unix.


Unified win.sign key

All Windows code signing is configured under a single win.sign key using a discriminated union with an explicit type field:

win.sign valueBehaviorPlatforms
unsetSign using credentials discovered from the environment — WIN_CSC_LINK / CSC_LINK with WIN_CSC_KEY_PASSWORD / CSC_KEY_PASSWORDall
{ type: "signtool", ... }Local .pfx/.p12 certificate file or Windows certificate storeWindows (signtool.exe) · macOS/Linux (osslsigncode)
{ type: "hsm", ... }Hardware Security Module / FIPS token via a Windows CSP — BetaWindows only
{ type: "pkcs11", ... }PKCS#11 hardware token via osslsigncodeBetamacOS/Linux
{ type: "azure", ... }Azure Trusted Signing cloud service — Betaall (signtool /dlib, Wine on macOS/Linux)
false or nullDisable signing (resedit resource editing still runs)all

Combining win.sign: false with forceCodeSigning: true is a configuration error and fails the build.


Signtool Signing (type: "signtool")

The standard signing mode, and the default when win.sign is unset. Signs with a local certificate file (.pfx/.p12) or a certificate from the Windows certificate store, using Microsoft signtool.exe on Windows and osslsigncode on macOS/Linux.

Setup

Set environment variables (recommended for CI):

WIN_CSC_LINK=/path/to/cert.pfx # or base64-encoded file contents
WIN_CSC_KEY_PASSWORD=your-cert-password

Or specify the certificate directly in config:

{
"win": {
"sign": {
"type": "signtool",
"certificateFile": "cert.pfx",
"certificatePassword": "...",
"signingHashAlgorithms": ["sha256"]
}
}
}

For EV certificates (bound to a USB dongle), identify by subject name instead:

{
"win": {
"sign": {
"type": "signtool",
"certificateSubjectName": "My Company, Inc."
}
}
}

Execution flow

  1. The certificate is resolved from certificateFile (or the WIN_CSC_LINK / CSC_LINK env var), or looked up in the Windows certificate store by certificateSubjectName / certificateSha1.
  2. Each file is signed once per entry in signingHashAlgorithms — by default SHA-1, then SHA-256 with the second signature appended as a nested signature.
  3. On Windows the signer is Microsoft signtool.exe; on macOS/Linux it is osslsigncode from the winCodeSign toolset bundle — no Wine or Windows VM is involved. Note: certificate-store lookups (certificateSubjectName / certificateSha1) read the Windows store and therefore require Windows (or the bundled Windows VM), whereas file-based signing works on any platform.

Configuration reference

Interface: WindowsSigntoolSigningConfig

Sign with a certificate file (.pfx / .p12) or with a certificate from the Windows certificate store, using Microsoft signtool.exe on Windows and osslsigncode on macOS/Linux. This is the default mode when win.sign is unset. Supply the certificate one of four ways: a file via certificateFile (or the WIN_CSC_LINK env var), or a store lookup via certificateSubjectName or certificateSha1.

Extends

  • WindowsSigningSharedOptions

Properties

additionalCertificateFile?

readonly optional additionalCertificateFile?: string | null

Path to an additional certificate file (typically an intermediate / cross-signing CA certificate) whose contents are added to the signature block via signtool's /ac flag. Use this when the signing certificate's full chain is not already present on target machines and you want it embedded in the signature so the chain can be validated.

Inherited from

WindowsSigningSharedOptions.additionalCertificateFile


certificateFile?

readonly optional certificateFile?: string | null

Path to the PKCS#12 certificate file (.pfx or .p12) holding both the signing certificate and its private key. Passed to signtool via /f (or osslsigncode via -pkcs12).

Prefer supplying this out-of-band via the WIN_CSC_LINK (or CSC_LINK) environment variable instead of hardcoding a path — that variable also accepts an https:// URL or a base64-encoded certificate, which is safer and more convenient on CI. See Code Signing.


certificatePassword?

readonly optional certificatePassword?: string | null

The password protecting the private key in certificateFile. Passed to signtool via /p (or osslsigncode via -pass).

Prefer the WIN_CSC_KEY_PASSWORD (or CSC_KEY_PASSWORD) environment variable so the secret never lands in your build configuration.


certificateSha1?

readonly optional certificateSha1?: string | null

Select the signing certificate from the Windows certificate store by its SHA-1 thumbprint, instead of pointing at a .pfx file. electron-builder looks the certificate up in the store and signs with /sha1 <thumbprint> /s <store>. Like certificateSubjectName, this suits EV certificates backed by a hardware token; if both are set, both must resolve to the same certificate.

Works only on Windows (or macOS with Parallels Desktop, via the bundled Windows VM).


certificateSubjectName?

readonly optional certificateSubjectName?: string | null

Select the signing certificate from the Windows certificate store by (a substring of) its subject name, instead of pointing at a .pfx file. electron-builder enumerates the installed code-signing certificates, picks the match, and signs by its thumbprint (/sha1 <thumbprint> /s <store>). Required for EV (Extended Validation) certificates, whose private keys live on a hardware token and cannot be exported to a file.

Works only on Windows (or macOS with Parallels Desktop, via the bundled Windows VM).


publisherName?

readonly optional publisherName?: string | string[] | null

The publisher name(s) to associate with the signature, written exactly as the subject appears in your code signing certificate. May be a single string or an array — an array is useful when rotating certificates, so updates signed by either the old or the new certificate still verify.

This value is not a signtool argument; it is consumed in two places:

  • Update verification — when verifyUpdateCodeSignature is enabled, it is written into app-update.yml and electron-updater checks it against the certificate that signed each downloaded update.
  • AppX / MSIX identity — the package Publisher attribute must equal the certificate subject, so electron-builder derives it from this value (or the certificate) to keep them in sync; a mismatch makes packaging fail with ERROR_BAD_FORMAT.

Defaults to the Common Name (CN) extracted from your code signing certificate. Set to null to opt out.

See

https://github.com/electron-userland/electron-builder/issues/1187#issuecomment-278972073

Inherited from

WindowsSigningSharedOptions.publisherName


rfc3161TimeStampServer?

readonly optional rfc3161TimeStampServer?: string | null

The URL of the RFC 3161 timestamp server, used for SHA-256 and nested/appended signatures (signtool's /tr flag). Timestamping records when the file was signed so the signature stays valid after the signing certificate expires. Ignored when the build runs with ELECTRON_BUILDER_OFFLINE=true.

Default

http://timestamp.digicert.com

Inherited from

WindowsSigningSharedOptions.rfc3161TimeStampServer


sign?

readonly optional sign?: string | CustomWindowsSign | null

A custom signing hook that replaces electron-builder's built-in signtool / osslsigncode invocation. Provide a function, or the path / module id of a file that exports a sign function (resolved relative to the project, then as a module).

The hook is invoked once per signing pass (i.e. once per entry in signingHashAlgorithms) and receives a configuration object describing the file to sign (path), the resolved certificate info (cscInfo), the current hash, and whether this pass is a nested signature (isNest), plus a computeSignToolArgs(isWin) helper that returns the default arguments electron-builder would otherwise have used. Use this to integrate an external or cloud signing service. See Code Signing.

Inherited from

WindowsSigningSharedOptions.sign


signingHashAlgorithms?

readonly optional signingHashAlgorithms?: ("sha256" | "sha1")[] | null

The digest (hash) algorithms to sign with, applied via signtool's /fd flag (or osslsigncode's -h). One signing pass runs per entry, in order; listing more than one dual-signs the file, with each additional signature appended as a nested signature (signtool /as). Signing with both sha1 and sha256 lets a single binary validate on legacy (pre-SHA-2) Windows as well as modern Windows.

Some targets override this: .msi cannot be dual-signed (a single hash is used) and AppX/MSIX is always sha256 only.

Default

['sha1', 'sha256']

Inherited from

WindowsSigningSharedOptions.signingHashAlgorithms


timeStampServer?

readonly optional timeStampServer?: string | null

The URL of the legacy Authenticode timestamp server, used for SHA-1 signatures (signtool's /t flag). This is also the timestamp server used by osslsigncode (-t) when signing on macOS/Linux. See rfc3161TimeStampServer for SHA-256 / nested signatures. Ignored when the build runs with ELECTRON_BUILDER_OFFLINE=true.

Default

http://timestamp.digicert.com

Inherited from

WindowsSigningSharedOptions.timeStampServer


type

readonly type: "signtool"

Discriminator selecting the default file/store signing mode.


HSM Signing (type: "hsm") — Beta

Beta feature

HSM signing is available in v27 as a beta feature. The configuration interface is stable, but real-hardware test coverage is limited. Please report issues if you encounter problems.

Signs using a Hardware Security Module (HSM), FIPS-compliant token, or smart card via signtool.exe's /csp (cryptographic service provider) and /kc (key container) flags. The private key never leaves the hardware; only the public certificate chain needs to be accessible to electron-builder.

Platform: Windows only. For macOS/Linux CI without a Windows VM, use type: "pkcs11" instead.

Requirement: a modern winCodeSign toolset, which is the default — you do not need to pin a version. Only an explicit legacy pin (toolsets.winCodeSign: "0.0.0") is unsupported, because it predates the required signtool version.

Setup

  1. Install the CSP driver for your HSM/token on the build machine. Examples:
  2. Obtain the certificate chain file (.crt, .cer, or .pfx — public key only).
  3. Configure electron-builder:
{
"win": {
"sign": {
"type": "hsm",
"cryptoServiceProvider": "Google Cloud KMS Provider",
"keyContainer": "projects/my-project/locations/us-east1/keyRings/my-ring/cryptoKeys/my-key/cryptoKeyVersions/1",
"certificateFile": "chain.crt"
}
}
}

The default winCodeSign toolset already supports HSM signing, so no toolsets pin is needed.

Execution flow

  1. signtool.exe sign is invoked with /csp <cryptoServiceProvider> and /kc <keyContainer>.
  2. The certificate is identified via certificateFile, certificateSha1, or certificateSubjectName.
  3. The HSM performs the private-key operation; the resulting signature is embedded by signtool.
  4. By default the file is dual-signed (SHA-1, then SHA-256), the same as the signtool mode — the HSM performs a key operation for each pass. Set signingHashAlgorithms: ["sha256"] to produce a single SHA-256 signature instead.

Caveats

  • Windows only. The /csp and /kc flags are signtool-specific. On macOS/Linux, use type: "pkcs11".
  • The CSP driver must be installed on the machine where the build runs (not available in most cloud CI environments without extra setup).
  • certificateFile, certificateSha1, or certificateSubjectName must be provided — HSM signing requires a certificate identifier (unlike signtool where the cert can be embedded in the token implicitly).

Configuration reference

Interface: WindowsHsmSigningConfig

Beta

HSM signing is available in v27 as a beta feature. The interface is stable but real-hardware test coverage is limited.

Extends

  • WindowsSigningSharedOptions

Properties

additionalCertificateFile?

readonly optional additionalCertificateFile?: string | null

Beta

Path to an additional certificate file (typically an intermediate / cross-signing CA certificate) whose contents are added to the signature block via signtool's /ac flag. Use this when the signing certificate's full chain is not already present on target machines and you want it embedded in the signature so the chain can be validated.

Inherited from

WindowsSigningSharedOptions.additionalCertificateFile


certificateFile?

readonly optional certificateFile?: string | null

Beta

Path to the certificate file containing the public certificate chain (.crt / .cer / .pfx). The private key is NOT read from this file — it is provided by the HSM via cryptoServiceProvider.


certificateSha1?

readonly optional certificateSha1?: string | null

Beta

Alternative to certificateFile: locate the public certificate in the Windows certificate store by its SHA-1 thumbprint. The private key still comes from the HSM via cryptoServiceProvider / keyContainer; this only identifies which public certificate to sign with.


certificateSubjectName?

readonly optional certificateSubjectName?: string | null

Beta

Alternative to certificateFile: locate the public certificate in the Windows certificate store by (a substring of) its subject name. The private key still comes from the HSM via cryptoServiceProvider / keyContainer; this only identifies which public certificate to sign with.


cryptoServiceProvider

readonly cryptoServiceProvider: string

Beta

The name of the cryptographic service provider (CSP) that holds the private key. Maps to signtool's /csp flag. Examples:

  • Google Cloud KMS: "Google Cloud KMS Provider"
  • Smart card / FIPS token: "Microsoft Base Smart Card Crypto Provider"

Requires a modern winCodeSign toolset (the default; only the legacy "0.0.0" pin is unsupported). Windows-only — use type: "pkcs11" on macOS/Linux.


keyContainer

readonly keyContainer: string

Beta

The key container name within the CSP. Maps to signtool's /kc flag.

Example for Google Cloud KMS: "projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY_NAME/cryptoKeyVersions/1"


publisherName?

readonly optional publisherName?: string | string[] | null

Beta

The publisher name(s) to associate with the signature, written exactly as the subject appears in your code signing certificate. May be a single string or an array — an array is useful when rotating certificates, so updates signed by either the old or the new certificate still verify.

This value is not a signtool argument; it is consumed in two places:

  • Update verification — when verifyUpdateCodeSignature is enabled, it is written into app-update.yml and electron-updater checks it against the certificate that signed each downloaded update.
  • AppX / MSIX identity — the package Publisher attribute must equal the certificate subject, so electron-builder derives it from this value (or the certificate) to keep them in sync; a mismatch makes packaging fail with ERROR_BAD_FORMAT.

Defaults to the Common Name (CN) extracted from your code signing certificate. Set to null to opt out.

See

https://github.com/electron-userland/electron-builder/issues/1187#issuecomment-278972073

Inherited from

WindowsSigningSharedOptions.publisherName


rfc3161TimeStampServer?

readonly optional rfc3161TimeStampServer?: string | null

Beta

The URL of the RFC 3161 timestamp server, used for SHA-256 and nested/appended signatures (signtool's /tr flag). Timestamping records when the file was signed so the signature stays valid after the signing certificate expires. Ignored when the build runs with ELECTRON_BUILDER_OFFLINE=true.

Default

http://timestamp.digicert.com

Inherited from

WindowsSigningSharedOptions.rfc3161TimeStampServer


sign?

readonly optional sign?: string | CustomWindowsSign | null

Beta

A custom signing hook that replaces electron-builder's built-in signtool / osslsigncode invocation. Provide a function, or the path / module id of a file that exports a sign function (resolved relative to the project, then as a module).

The hook is invoked once per signing pass (i.e. once per entry in signingHashAlgorithms) and receives a configuration object describing the file to sign (path), the resolved certificate info (cscInfo), the current hash, and whether this pass is a nested signature (isNest), plus a computeSignToolArgs(isWin) helper that returns the default arguments electron-builder would otherwise have used. Use this to integrate an external or cloud signing service. See Code Signing.

Inherited from

WindowsSigningSharedOptions.sign


signingHashAlgorithms?

readonly optional signingHashAlgorithms?: ("sha256" | "sha1")[] | null

Beta

The digest (hash) algorithms to sign with, applied via signtool's /fd flag (or osslsigncode's -h). One signing pass runs per entry, in order; listing more than one dual-signs the file, with each additional signature appended as a nested signature (signtool /as). Signing with both sha1 and sha256 lets a single binary validate on legacy (pre-SHA-2) Windows as well as modern Windows.

Some targets override this: .msi cannot be dual-signed (a single hash is used) and AppX/MSIX is always sha256 only.

Default

['sha1', 'sha256']

Inherited from

WindowsSigningSharedOptions.signingHashAlgorithms


timeStampServer?

readonly optional timeStampServer?: string | null

Beta

The URL of the legacy Authenticode timestamp server, used for SHA-1 signatures (signtool's /t flag). This is also the timestamp server used by osslsigncode (-t) when signing on macOS/Linux. See rfc3161TimeStampServer for SHA-256 / nested signatures. Ignored when the build runs with ELECTRON_BUILDER_OFFLINE=true.

Default

http://timestamp.digicert.com

Inherited from

WindowsSigningSharedOptions.timeStampServer


type

readonly type: "hsm"

Beta

Discriminator selecting HSM / hardware-token signing via signtool's /csp and /kc flags.


PKCS#11 Signing (type: "pkcs11") — Beta

Beta feature

PKCS#11 signing is available in v27 as a beta feature. The configuration interface is stable, but real-hardware test coverage is limited. Please report issues if you encounter problems.

Signs using a PKCS#11 hardware token via osslsigncode. Unlike HSM signing, this works on macOS and Linux without a Windows VM, making it suitable for cloud CI environments where a physical token is accessible via network HSM or PKCS#11-over-network software.

Platform: macOS and Linux only (uses osslsigncode). On Windows, use type: "hsm" instead.

Setup

  1. Install the PKCS#11 shared library for your token. Examples:
    • OpenSC (smart cards): sudo apt install opensc or brew install opensc
    • SoftHSM (testing): sudo apt install softhsm2
    • AWS CloudHSM: the CloudHSM PKCS#11 library
  2. Confirm the module path and key URI using pkcs11-tool --list-objects or your provider's tooling.
  3. Configure electron-builder:
{
"win": {
"sign": {
"type": "pkcs11",
"pkcs11Module": "/usr/lib/x86_64-linux-gnu/opensc-pkcs11.so",
"pkcs11KeyUri": "pkcs11:token=MyToken;object=MyKey;type=private"
}
}
}

With an optional external certificate chain file (if the token does not carry the full chain):

{
"win": {
"sign": {
"type": "pkcs11",
"pkcs11Module": "/usr/lib/x86_64-linux-gnu/opensc-pkcs11.so",
"pkcs11KeyUri": "pkcs11:token=MyToken;object=MyKey;type=private",
"certificateFile": "chain.crt"
}
}
}

Token PIN

ScenarioHow to supply the PIN
certificateFile setWIN_CSC_KEY_PASSWORD or CSC_KEY_PASSWORD env var
No certificateFile (token holds cert)Same env vars, or embed directly in the URI: pkcs11:...?pin-value=<pin>

Execution flow

  1. osslsigncode sign is invoked with -pkcs11module and -key (the RFC 7512 URI).
  2. If certificateFile is set, -certs is added for the chain; otherwise the cert embedded in the token is used.
  3. If a PIN is available via env var, -pass is appended.
  4. SHA1 and SHA256 signing are performed in sequence (like signtool dual-sign).

Caveats

  • macOS/Linux only. Throws InvalidConfigurationError when called on Windows; use type: "hsm" on Windows.
  • The osslsigncode binary is bundled in the winCodeSign toolset — no manual installation needed.
  • The PKCS#11 shared library (.so / .dylib) must be installed separately on the build machine.
  • Network or USB token latency can make large builds slow. Consider signing only final installers rather than every intermediate .exe.

Configuration reference

Interface: WindowsPkcs11SigningConfig

Beta

Sign with a PKCS#11 hardware token (smart card, USB HSM, cloud KMS exposed via a PKCS#11 provider) using osslsigncode. Unlike hsm, this mode does not require Windows or a Windows VM, so it can sign Windows binaries directly from macOS/Linux CI. The token PIN is read from the WIN_CSC_KEY_PASSWORD (or CSC_KEY_PASSWORD) environment variable.

PKCS#11 signing is available in v27 as a beta feature. The interface is stable but real-hardware test coverage is limited.

Extends

  • WindowsSigningSharedOptions

Properties

additionalCertificateFile?

readonly optional additionalCertificateFile?: string | null

Beta

Path to an additional certificate file (typically an intermediate / cross-signing CA certificate) whose contents are added to the signature block via signtool's /ac flag. Use this when the signing certificate's full chain is not already present on target machines and you want it embedded in the signature so the chain can be validated.

Inherited from

WindowsSigningSharedOptions.additionalCertificateFile


certificateFile?

readonly optional certificateFile?: string | null

Beta

Optional path to a certificate chain file to accompany the PKCS#11 key. If omitted the certificate embedded in the token is used.


pkcs11KeyUri

readonly pkcs11KeyUri: string

Beta

RFC 7512 PKCS#11 URI identifying the private key within the module. Maps to osslsigncode's -key parameter.

Example: "pkcs11:token=MyToken;object=MyKey;type=private"

Must be paired with pkcs11Module.


pkcs11Module

readonly pkcs11Module: string

Beta

Path to the PKCS#11 shared library (.so on Linux, .dylib on macOS). The library must be installed separately — electron-builder does not bundle it.

Example: "/usr/lib/x86_64-linux-gnu/opensc-pkcs11.so"

Must be paired with pkcs11KeyUri.


publisherName?

readonly optional publisherName?: string | string[] | null

Beta

The publisher name(s) to associate with the signature, written exactly as the subject appears in your code signing certificate. May be a single string or an array — an array is useful when rotating certificates, so updates signed by either the old or the new certificate still verify.

This value is not a signtool argument; it is consumed in two places:

  • Update verification — when verifyUpdateCodeSignature is enabled, it is written into app-update.yml and electron-updater checks it against the certificate that signed each downloaded update.
  • AppX / MSIX identity — the package Publisher attribute must equal the certificate subject, so electron-builder derives it from this value (or the certificate) to keep them in sync; a mismatch makes packaging fail with ERROR_BAD_FORMAT.

Defaults to the Common Name (CN) extracted from your code signing certificate. Set to null to opt out.

See

https://github.com/electron-userland/electron-builder/issues/1187#issuecomment-278972073

Inherited from

WindowsSigningSharedOptions.publisherName


rfc3161TimeStampServer?

readonly optional rfc3161TimeStampServer?: string | null

Beta

The URL of the RFC 3161 timestamp server, used for SHA-256 and nested/appended signatures (signtool's /tr flag). Timestamping records when the file was signed so the signature stays valid after the signing certificate expires. Ignored when the build runs with ELECTRON_BUILDER_OFFLINE=true.

Default

http://timestamp.digicert.com

Inherited from

WindowsSigningSharedOptions.rfc3161TimeStampServer


sign?

readonly optional sign?: string | CustomWindowsSign | null

Beta

A custom signing hook that replaces electron-builder's built-in signtool / osslsigncode invocation. Provide a function, or the path / module id of a file that exports a sign function (resolved relative to the project, then as a module).

The hook is invoked once per signing pass (i.e. once per entry in signingHashAlgorithms) and receives a configuration object describing the file to sign (path), the resolved certificate info (cscInfo), the current hash, and whether this pass is a nested signature (isNest), plus a computeSignToolArgs(isWin) helper that returns the default arguments electron-builder would otherwise have used. Use this to integrate an external or cloud signing service. See Code Signing.

Inherited from

WindowsSigningSharedOptions.sign


signingHashAlgorithms?

readonly optional signingHashAlgorithms?: ("sha256" | "sha1")[] | null

Beta

The digest (hash) algorithms to sign with, applied via signtool's /fd flag (or osslsigncode's -h). One signing pass runs per entry, in order; listing more than one dual-signs the file, with each additional signature appended as a nested signature (signtool /as). Signing with both sha1 and sha256 lets a single binary validate on legacy (pre-SHA-2) Windows as well as modern Windows.

Some targets override this: .msi cannot be dual-signed (a single hash is used) and AppX/MSIX is always sha256 only.

Default

['sha1', 'sha256']

Inherited from

WindowsSigningSharedOptions.signingHashAlgorithms


timeStampServer?

readonly optional timeStampServer?: string | null

Beta

The URL of the legacy Authenticode timestamp server, used for SHA-1 signatures (signtool's /t flag). This is also the timestamp server used by osslsigncode (-t) when signing on macOS/Linux. See rfc3161TimeStampServer for SHA-256 / nested signatures. Ignored when the build runs with ELECTRON_BUILDER_OFFLINE=true.

Default

http://timestamp.digicert.com

Inherited from

WindowsSigningSharedOptions.timeStampServer


type

readonly type: "pkcs11"

Beta

Discriminator selecting cross-platform PKCS#11 token signing via osslsigncode.


Azure Trusted Signing (type: "azure") — Beta

Beta feature

The signtool /dlib Azure Trusted Signing integration introduced in v27 is a beta feature. It is the default path on current toolsets; the legacy PowerShell fallback remains available only when you explicitly pin toolsets.winCodeSign below "1.3.0" (see Legacy PowerShell fallback below). Please report issues if you encounter problems.

Microsoft's cloud-based code signing service. No certificate file or private key is managed locally — authentication is via Azure Entra ID environment variables and signing is performed by the Azure service.

Azure account setup

If you do not already have an Azure setup and only want to use their code signing service, set up an Azure "Trusted Signing Account" using this quickstart guide. Then, set up an "App registration" in Azure, follow the steps to create a "Secret" for it, and assign the role "Trusted Signing Certificate Profile Signer" to the App registration (note, the App registration is considered a "service principal" and you will need to type its name into the search bar to find it in the web panel).

Setup

Set the required environment variables (descriptions from Azure.Identity — EnvironmentCredential):

Env varDescription
AZURE_TENANT_IDYour Azure AD Tenant ID; found in the Entra ID portal
AZURE_CLIENT_IDApplication (Client) ID of your App registration — not the object ID
AZURE_CLIENT_SECRETValue of the Secret you created — not the secret's ID
AZURE_CLIENT_CERTIFICATE_PATHRequired if using your own certificate for authentication
AZURE_CLIENT_SEND_CERTIFICATE_CHAINRequired if using your own certificate for authentication
AZURE_USERNAMEMicrosoft Entra account username (for interactive/password flows)
AZURE_PASSWORDMicrosoft Entra account password (for interactive/password flows)
AZURE_FEDERATED_TOKEN_FILEFor workload identity federation (e.g. GitHub Actions OIDC)
tip

If you use the minimal setup with an "App registration" as described above, only AZURE_TENANT_ID, AZURE_CLIENT_ID, and AZURE_CLIENT_SECRET are needed.

Then configure win.sign. The default toolset already ships the /dlib integration, so no winCodeSign pin is required:

{
"win": {
"sign": {
"type": "azure",
"publisherName": "CN=My Company, O=My Company, C=US",
"endpoint": "https://weu.codesigning.azure.net/",
"codeSigningAccountName": "my-trusted-signing-account",
"certificateProfileName": "my-cert-profile"
}
}
}

Execution flow

  1. electron-builder writes a metadata.json file containing Endpoint, CodeSigningAccountName, CertificateProfileName, and any additionalMetadata fields.
  2. signtool.exe sign /dlib Azure.CodeSigning.Dlib.dll /dmdf metadata.json is invoked. The DLib authenticates to Azure using DefaultAzureCredential (reads the env vars above automatically).
  3. On macOS/Linux, signtool.exe runs inside Wine using the winCodeSign toolset bundle — no separate Windows VM required.

Extra metadata fields

Use additionalMetadata to pass extra fields verbatim into metadata.json. This covers DLib-specific options not exposed as typed fields:

{
"win": {
"sign": {
"type": "azure",
"endpoint": "https://weu.codesigning.azure.net/",
"codeSigningAccountName": "my-account",
"certificateProfileName": "my-profile",
"publisherName": "CN=My Company",
"additionalMetadata": {
"ExcludeCredentials": "ManagedIdentityCredential",
"CorrelationId": "my-build-run-id"
}
}
}
}

Legacy PowerShell fallback

The default toolset (winCodeSign unset, null, or "latest") resolves to the newest bundle (1.3.0+) and uses the modern signtool /dlib path. Only if you explicitly pin toolsets.winCodeSign below "1.3.0" (for example "1.2.1", or the legacy "0.0.0") does electron-builder fall back to the v26 PowerShell Invoke-TrustedSigning integration and emit a deprecation warning. This fallback will be removed in a future release, so avoid pinning an older toolset unless you specifically need it.

Caveats

  • The ats-bundle (containing Azure.CodeSigning.Dlib.dll and its native dependency closure) and the dotnet-runtime bundle ship with winCodeSign "1.3.0" and later — which is the default. They are downloaded automatically on first use; no manual setup or toolset pin is required.
  • The DLib is a mixed-mode .NET 8 assembly: electron-builder automatically downloads and provides the .NET 8 runtime via the separate dotnet-runtime bundle — no manual runtime installation is required.
  • The DLib authenticates using the Azure environment variables at signing time — credentials are not embedded in config.
  • Network connectivity to the Azure endpoint is required during the build. Rate limits or outages will fail the build.

Configuration reference

Interface: WindowsAzureSigningConfig

The signtool /dlib Azure Trusted Signing integration was introduced in toolsets.winCodeSign: 1.3.0. The legacy PowerShell integration is deprecated, but leverages the same underlying Azure APIs, so both interfaces share the same config shape.

Properties

additionalMetadata?

readonly optional additionalMetadata?: Record<string, string>

Additional fields to include verbatim in the metadata.json file passed to Azure.CodeSigning.Dlib.dll via signtool /dmdf. Use this for DLib-specific options not covered by the typed fields above (e.g. ExcludeCredentials, CorrelationId).


certificateProfileName

readonly certificateProfileName: string

The name of the Trusted Signing Certificate Profile to sign with, as created in your Azure Code Signing Account. Maps to the DLib metadata field CertificateProfileName.


codeSigningAccountName

readonly codeSigningAccountName: string

The name of the Azure Trusted Signing (Code Signing) Account that owns the certificate profile. Maps to the DLib metadata field CodeSigningAccountName.


endpoint

readonly endpoint: string

The Trusted Signing Account endpoint. The URI value must align to the region your Trusted Signing Account and Certificate Profile were created in.

Requires Azure Entra ID environment variables per Microsoft's documentation.


fileDigest?

readonly optional fileDigest?: string

The digest algorithm used to hash the files being signed. Maps to the DLib metadata field FileDigest.

Default

SHA256

publisherName

readonly publisherName: string

The publisher name to associate with the signature, exactly as it appears in the certificate issued by your Trusted Signing certificate profile. Required. Used for update verification (embedded in app-update.yml and checked by electron-updater) and must match the certificate subject.

See

https://github.com/electron-userland/electron-builder/issues/1187#issuecomment-278972073


timestampDigest?

readonly optional timestampDigest?: string

The timestamp digest algorithm. Translates to field: TimestampDigest.

Default

SHA256

timestampRfc3161?

readonly optional timestampRfc3161?: string

The RFC3161 timestamp server. Translates to field: TimestampRfc3161.

Default

http://timestamp.acs.microsoft.com

type

readonly type: "azure"

Discriminator selecting Azure Trusted Signing (cloud signing — no local certificate).