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.
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/.p12file or a certificate already in the Windows certificate store. Signs with Microsoftsigntool.exeon Windows andosslsigncodeon 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 viaosslsigncode. - 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 thesigntoolmethod. - 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
certificateSubjectNameorcertificateSha1rather than a file path, and sign with thehsm(Windows) orpkcs11(macOS/Linux) method — or switch toazureto avoid managing hardware at all.
Both grades work with auto-update.
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 value | Behavior | Platforms |
|---|---|---|
| unset | Sign using credentials discovered from the environment — WIN_CSC_LINK / CSC_LINK with WIN_CSC_KEY_PASSWORD / CSC_KEY_PASSWORD | all |
{ type: "signtool", ... } | Local .pfx/.p12 certificate file or Windows certificate store | Windows (signtool.exe) · macOS/Linux (osslsigncode) |
{ type: "hsm", ... } | Hardware Security Module / FIPS token via a Windows CSP — Beta | Windows only |
{ type: "pkcs11", ... } | PKCS#11 hardware token via osslsigncode — Beta | macOS/Linux |
{ type: "azure", ... } | Azure Trusted Signing cloud service — Beta | all (signtool /dlib, Wine on macOS/Linux) |
false or null | Disable 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
- The certificate is resolved from
certificateFile(or theWIN_CSC_LINK/CSC_LINKenv var), or looked up in the Windows certificate store bycertificateSubjectName/certificateSha1. - 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. - On Windows the signer is Microsoft
signtool.exe; on macOS/Linux it isosslsigncodefrom thewinCodeSigntoolset 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?
readonlyoptionaladditionalCertificateFile?: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?
readonlyoptionalcertificateFile?: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?
readonlyoptionalcertificatePassword?: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?
readonlyoptionalcertificateSha1?: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?
readonlyoptionalcertificateSubjectName?: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?
readonlyoptionalpublisherName?: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.ymland electron-updater checks it against the certificate that signed each downloaded update. - AppX / MSIX identity — the package
Publisherattribute 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 withERROR_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?
readonlyoptionalrfc3161TimeStampServer?: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?
readonlyoptionalsign?: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?
readonlyoptionalsigningHashAlgorithms?: ("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?
readonlyoptionaltimeStampServer?: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
readonlytype:"signtool"
Discriminator selecting the default file/store signing mode.
HSM Signing (type: "hsm") — Beta
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
- Install the CSP driver for your HSM/token on the build machine. Examples:
- Google Cloud KMS: the Cloud KMS Windows CNG Provider.
- Smart card / FIPS token:
"Microsoft Base Smart Card Crypto Provider"(built into Windows).
- Obtain the certificate chain file (
.crt,.cer, or.pfx— public key only). - 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
signtool.exe signis invoked with/csp <cryptoServiceProvider>and/kc <keyContainer>.- The certificate is identified via
certificateFile,certificateSha1, orcertificateSubjectName. - The HSM performs the private-key operation; the resulting signature is embedded by signtool.
- By default the file is dual-signed (SHA-1, then SHA-256), the same as the
signtoolmode — the HSM performs a key operation for each pass. SetsigningHashAlgorithms: ["sha256"]to produce a single SHA-256 signature instead.
Caveats
- Windows only. The
/cspand/kcflags are signtool-specific. On macOS/Linux, usetype: "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, orcertificateSubjectNamemust 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?
readonlyoptionaladditionalCertificateFile?: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?
readonlyoptionalcertificateFile?: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?
readonlyoptionalcertificateSha1?: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?
readonlyoptionalcertificateSubjectName?: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
readonlycryptoServiceProvider: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
readonlykeyContainer: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?
readonlyoptionalpublisherName?: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.ymland electron-updater checks it against the certificate that signed each downloaded update. - AppX / MSIX identity — the package
Publisherattribute 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 withERROR_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?
readonlyoptionalrfc3161TimeStampServer?: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?
readonlyoptionalsign?: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?
readonlyoptionalsigningHashAlgorithms?: ("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?
readonlyoptionaltimeStampServer?: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
readonlytype:"hsm"
Beta
Discriminator selecting HSM / hardware-token signing via signtool's /csp and /kc flags.
PKCS#11 Signing (type: "pkcs11") — Beta
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
- Install the PKCS#11 shared library for your token. Examples:
- OpenSC (smart cards):
sudo apt install openscorbrew install opensc - SoftHSM (testing):
sudo apt install softhsm2 - AWS CloudHSM: the CloudHSM PKCS#11 library
- OpenSC (smart cards):
- Confirm the module path and key URI using
pkcs11-tool --list-objectsor your provider's tooling. - 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
| Scenario | How to supply the PIN |
|---|---|
certificateFile set | WIN_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
osslsigncode signis invoked with-pkcs11moduleand-key(the RFC 7512 URI).- If
certificateFileis set,-certsis added for the chain; otherwise the cert embedded in the token is used. - If a PIN is available via env var,
-passis appended. - SHA1 and SHA256 signing are performed in sequence (like signtool dual-sign).
Caveats
- macOS/Linux only. Throws
InvalidConfigurationErrorwhen called on Windows; usetype: "hsm"on Windows. - The
osslsigncodebinary is bundled in thewinCodeSigntoolset — 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?
readonlyoptionaladditionalCertificateFile?: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?
readonlyoptionalcertificateFile?: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
readonlypkcs11KeyUri: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
readonlypkcs11Module: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?
readonlyoptionalpublisherName?: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.ymland electron-updater checks it against the certificate that signed each downloaded update. - AppX / MSIX identity — the package
Publisherattribute 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 withERROR_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?
readonlyoptionalrfc3161TimeStampServer?: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?
readonlyoptionalsign?: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?
readonlyoptionalsigningHashAlgorithms?: ("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?
readonlyoptionaltimeStampServer?: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
readonlytype:"pkcs11"
Beta
Discriminator selecting cross-platform PKCS#11 token signing via osslsigncode.
Azure Trusted Signing (type: "azure") — Beta
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 var | Description |
|---|---|
AZURE_TENANT_ID | Your Azure AD Tenant ID; found in the Entra ID portal |
AZURE_CLIENT_ID | Application (Client) ID of your App registration — not the object ID |
AZURE_CLIENT_SECRET | Value of the Secret you created — not the secret's ID |
AZURE_CLIENT_CERTIFICATE_PATH | Required if using your own certificate for authentication |
AZURE_CLIENT_SEND_CERTIFICATE_CHAIN | Required if using your own certificate for authentication |
AZURE_USERNAME | Microsoft Entra account username (for interactive/password flows) |
AZURE_PASSWORD | Microsoft Entra account password (for interactive/password flows) |
AZURE_FEDERATED_TOKEN_FILE | For workload identity federation (e.g. GitHub Actions OIDC) |
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
- electron-builder writes a
metadata.jsonfile containingEndpoint,CodeSigningAccountName,CertificateProfileName, and anyadditionalMetadatafields. signtool.exe sign /dlib Azure.CodeSigning.Dlib.dll /dmdf metadata.jsonis invoked. The DLib authenticates to Azure usingDefaultAzureCredential(reads the env vars above automatically).- On macOS/Linux,
signtool.exeruns inside Wine using thewinCodeSigntoolset 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(containingAzure.CodeSigning.Dlib.dlland its native dependency closure) and thedotnet-runtimebundle ship withwinCodeSign "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-runtimebundle — 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?
readonlyoptionaladditionalMetadata?: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
readonlycertificateProfileName: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
readonlycodeSigningAccountName:string
The name of the Azure Trusted Signing (Code Signing) Account that owns the certificate profile.
Maps to the DLib metadata field CodeSigningAccountName.
endpoint
readonlyendpoint: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?
readonlyoptionalfileDigest?:string
The digest algorithm used to hash the files being signed. Maps to the DLib metadata field
FileDigest.
Default
SHA256
publisherName
readonlypublisherName: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?
readonlyoptionaltimestampDigest?:string
The timestamp digest algorithm. Translates to field: TimestampDigest.
Default
SHA256
timestampRfc3161?
readonlyoptionaltimestampRfc3161?:string
The RFC3161 timestamp server. Translates to field: TimestampRfc3161.
Default
http://timestamp.acs.microsoft.com
type
readonlytype:"azure"
Discriminator selecting Azure Trusted Signing (cloud signing — no local certificate).