Skip to content

Commit

Permalink
feat(win): implement Azure Trusted Signing (#8458)
Browse files Browse the repository at this point in the history
  • Loading branch information
mmaietta authored Sep 13, 2024
1 parent 55671bd commit d50d563
Show file tree
Hide file tree
Showing 30 changed files with 1,119 additions and 700 deletions.
5 changes: 5 additions & 0 deletions .changeset/tame-pets-jam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"app-builder-lib": minor
---

feat: Implement Azure Trusted Signing
307 changes: 127 additions & 180 deletions docs/api/electron-builder.md

Large diffs are not rendered by default.

29 changes: 24 additions & 5 deletions docs/code-signing.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ Windows is dual code-signed (SHA1 & SHA256 hashing algorithms).

On a macOS development machine, a valid and appropriate identity from your keychain will be automatically used.

!!! tip
!!! tip
See article [Notarizing your Electron application](https://kilianvalkhof.com/2019/electron/notarizing-your-electron-application/).


| Env Name | Description
| -------------- | -----------
Expand All @@ -29,7 +29,7 @@ To sign an app on Windows, there are two types of certificates:
* EV Code Signing Certificate
* Code Signing Certificate

Both certificates work with auto-update. The regular (and often cheaper) Code Signing Certificate shows a warning during installation that goes away once enough users installed your application and you've built up trust. The EV Certificate has more trust and thus works immediately without any warnings. However, it is not possible to export the EV Certificate as it is bound to a physical USB dongle. Thus, you can't export the certificate for signing code on a CI, such as AppVeyor.
Both certificates work with auto-update. The regular (and often cheaper) Code Signing Certificate shows a warning during installation that goes away once enough users installed your application and you've built up trust. The EV Certificate has more trust and thus works immediately without any warnings. However, it is not possible to export the EV Certificate as it is bound to a physical USB dongle. Thus, you can't export the certificate for signing code on a CI, such as AppVeyor.

If you are using an EV Certificate, you need to provide [win.certificateSubjectName](configuration/win.md#WindowsConfiguration-certificateSubjectName) in your electron-builder configuration.

Expand All @@ -52,7 +52,7 @@ To sign app on build server you need to set `CSC_LINK`, `CSC_KEY_PASSWORD`:
In case of AppVeyor, don't forget to click on lock icon to “Toggle variable encryption”.

Keep in mind that Windows is not able to handle enviroment variable values longer than 8192 characters, thus if the base64 representation of your certificate exceeds that limit, try re-exporting the certificate without including all the certificates in the certification path (they are not necessary, but the Certificate Manager export wizard ticks the option by default), otherwise the encoded value will be truncated.

[1] `printf "%q\n" "<url>"`

## Where to Buy Code Signing Certificate
Expand All @@ -75,10 +75,29 @@ Please note — Gatekeeper only recognises [Apple digital certificates](http://s

## How to Disable Code Signing During the Build Process on macOS

To disable Code Signing when building for macOS leave all the above vars unset except for `CSC_IDENTITY_AUTO_DISCOVERY` which needs to be set to `false`. This can be done by running `export CSC_IDENTITY_AUTO_DISCOVERY=false`.
To disable Code Signing when building for macOS leave all the above vars unset except for `CSC_IDENTITY_AUTO_DISCOVERY` which needs to be set to `false`. This can be done by running `export CSC_IDENTITY_AUTO_DISCOVERY=false`.

Another way — set `mac.identity` to `null`. You can pass aditional configuration using CLI as well: `-c.mac.identity=null`.

## Using with Azure Trusted Signing (beta)

To sign using Azure Tenant account, you'll need the following env variables set that are read directly by `Invoke-TrustedSigning` module; they are not parsed or resolved by electron-builder.

!!! tip
Descriptions of each field can be found here: [Azure.Identity class - EnvironmentCredential Class](https://learn.microsoft.com/en-us/dotnet/api/azure.identity.environmentcredential?view=azure-dotnet#definition)

| Env Name | Description
| -------------- | -----------
| `AZURE_TENANT_ID` | See the Tip mentioned above.
| `AZURE_CLIENT_ID` |
| `AZURE_CLIENT_SECRET` |
| `AZURE_CLIENT_CERTIFICATE_PATH` |
| `AZURE_CLIENT_SEND_CERTIFICATE_CHAIN` |
| `AZURE_USERNAME` |
| `AZURE_PASSWORD` |

`win.azureOptions` needs to be configured per [Microsoft's instructions](https://learn.microsoft.com/en-us/azure/trusted-signing/how-to-signing-integrations#create-a-json-file) directly in electron-builder's configuration. Additional fields can be provided that are passed directly to `Invoke-TrustedSigning` powershell command.

## Alternative methods of codesigning

Codesigning via Electron Builder's configuration (via package.json) is not the only way to sign an application. Some people find it easier to codesign using a GUI tool. A couple of examples include:
Expand Down
54 changes: 44 additions & 10 deletions docs/configuration/win.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,59 @@ The top-level [win](configuration.md#Configuration-win) key contains set of opti
</ul>
<hr>
<ul>
<li><code id="WindowsConfiguration-signingHashAlgorithms">signingHashAlgorithms</code> = <code>['sha1', 'sha256']</code> Array&lt;“sha256” | “sha1”&gt; | “undefined” - Array of signing algorithms used. For AppX <code>sha256</code> is always used.</li>
<li><code id="WindowsConfiguration-sign">sign</code> String | (configuration: CustomWindowsSignTaskConfiguration) =&gt; Promise - The custom function (or path to file or module id) to sign Windows executable.</li>
<li><code id="WindowsConfiguration-certificateFile">certificateFile</code> String | “undefined” - The path to the *.pfx certificate you want to sign with. Please use it only if you cannot use env variable <code>CSC_LINK</code> (<code>WIN_CSC_LINK</code>) for some reason. Please see <a href="/code-signing">Code Signing</a>.</li>
<li><code id="WindowsConfiguration-certificatePassword">certificatePassword</code> String | “undefined” - The password to the certificate provided in <code>certificateFile</code>. Please use it only if you cannot use env variable <code>CSC_KEY_PASSWORD</code> (<code>WIN_CSC_KEY_PASSWORD</code>) for some reason. Please see <a href="/code-signing">Code Signing</a>.</li>
<li><code id="WindowsConfiguration-certificateSubjectName">certificateSubjectName</code> String | “undefined” - The name of the subject of the signing certificate, which is often labeled with the field name <code>issued to</code>. Required only for EV Code Signing and works only on Windows (or on macOS if <a href="https://www.parallels.com/products/desktop/">Parallels Desktop</a> Windows 10 virtual machines exits).</li>
<li><code id="WindowsConfiguration-certificateSha1">certificateSha1</code> String | “undefined” - The SHA1 hash of the signing certificate. The SHA1 hash is commonly specified when multiple certificates satisfy the criteria specified by the remaining switches. Works only on Windows (or on macOS if <a href="https://www.parallels.com/products/desktop/">Parallels Desktop</a> Windows 10 virtual machines exits).</li>
<li><code id="WindowsConfiguration-additionalCertificateFile">additionalCertificateFile</code> String | “undefined” - The path to an additional certificate file you want to add to the signature block.</li>
<li><code id="WindowsConfiguration-rfc3161TimeStampServer">rfc3161TimeStampServer</code> = <code>http://timestamp.digicert.com</code> String | “undefined” - The URL of the RFC 3161 time stamp server.</li>
<li><code id="WindowsConfiguration-timeStampServer">timeStampServer</code> = <code>http://timestamp.digicert.com</code> String | “undefined” - The URL of the time stamp server.</li>
<li tag.description=""><code id="WindowsConfiguration-signingHashAlgorithms">signingHashAlgorithms</code> Array&lt;“sha256” | “sha1”&gt; | “undefined” - Array of signing algorithms used. For AppX <code>sha256</code> is always used. Deprecated:</li>
<li tag.description=""><code id="WindowsConfiguration-sign">sign</code> String | (configuration: CustomWindowsSignTaskConfiguration) =&gt; Promise - The custom function (or path to file or module id) to sign Windows executables Deprecated:</li>
<li tag.description=""><code id="WindowsConfiguration-certificateFile">certificateFile</code> String | “undefined” - The path to the *.pfx certificate you want to sign with. Please use it only if you cannot use env variable <code>CSC_LINK</code> (<code>WIN_CSC_LINK</code>) for some reason. Please see <a href="/code-signing">Code Signing</a>. Deprecated:</li>
<li tag.description=""><code id="WindowsConfiguration-certificatePassword">certificatePassword</code> String | “undefined” - The password to the certificate provided in <code>certificateFile</code>. Please use it only if you cannot use env variable <code>CSC_KEY_PASSWORD</code> (<code>WIN_CSC_KEY_PASSWORD</code>) for some reason. Please see <a href="/code-signing">Code Signing</a>. Deprecated:</li>
<li tag.description=""><code id="WindowsConfiguration-certificateSubjectName">certificateSubjectName</code> String | “undefined” - The name of the subject of the signing certificate, which is often labeled with the field name <code>issued to</code>. Required only for EV Code Signing and works only on Windows (or on macOS if <a href="https://www.parallels.com/products/desktop/">Parallels Desktop</a> Windows 10 virtual machines exits). Deprecated:</li>
<li tag.description=""><code id="WindowsConfiguration-certificateSha1">certificateSha1</code> String | “undefined” - The SHA1 hash of the signing certificate. The SHA1 hash is commonly specified when multiple certificates satisfy the criteria specified by the remaining switches. Works only on Windows (or on macOS if <a href="https://www.parallels.com/products/desktop/">Parallels Desktop</a> Windows 10 virtual machines exits). Deprecated:</li>
<li tag.description=""><code id="WindowsConfiguration-additionalCertificateFile">additionalCertificateFile</code> String | “undefined” - The path to an additional certificate file you want to add to the signature block. Deprecated:</li>
<li tag.description=""><code id="WindowsConfiguration-rfc3161TimeStampServer">rfc3161TimeStampServer</code> = <code>http://timestamp.digicert.com</code> String | “undefined” - The URL of the RFC 3161 time stamp server. Deprecated:</li>
<li tag.description=""><code id="WindowsConfiguration-timeStampServer">timeStampServer</code> = <code>http://timestamp.digicert.com</code> String | “undefined” - The URL of the time stamp server. Deprecated:</li>
</ul>
<hr>
<ul>
<li><code id="WindowsConfiguration-publisherName">publisherName</code> String | Array&lt;String&gt; | “undefined” - <a href="https://github.com/electron-userland/electron-builder/issues/1187#issuecomment-278972073">The publisher name</a>, exactly as in your code signed certificate. Several names can be provided. Defaults to common name from your code signing certificate.</li>
<li tag.description=""><code id="WindowsConfiguration-publisherName">publisherName</code> String | Array&lt;String&gt; | “undefined” - <a href="https://github.com/electron-userland/electron-builder/issues/1187#issuecomment-278972073">The publisher name</a>, exactly as in your code signed certificate. Several names can be provided. Defaults to common name from your code signing certificate. Deprecated:</li>
<li><code id="WindowsConfiguration-signtoolOptions">signtoolOptions</code> <a href="#WindowsSigntoolConfiguration">WindowsSigntoolConfiguration</a> | “undefined” - Options for usage with signtool.exe</li>
<li><code id="WindowsConfiguration-azureSignOptions">azureSignOptions</code> <a href="#WindowsAzureSigningConfiguration">WindowsAzureSigningConfiguration</a> | “undefined” - Options for usage of Azure Trusted Signing (beta)</li>
<li><code id="WindowsConfiguration-verifyUpdateCodeSignature">verifyUpdateCodeSignature</code> = <code>true</code> Boolean - Whether to verify the signature of an available update before installation. The <a href="#publisherName">publisher name</a> will be used for the signature verification.</li>
<li><code id="WindowsConfiguration-requestedExecutionLevel">requestedExecutionLevel</code> = <code>asInvoker</code> “asInvoker” | “highestAvailable” | “requireAdministrator” | “undefined” - The <a href="https://msdn.microsoft.com/en-us/library/6ad1fshk.aspx#Anchor_9">security level</a> at which the application requests to be executed. Cannot be specified per target, allowed only in the <code>win</code>.</li>
<li><code id="WindowsConfiguration-signAndEditExecutable">signAndEditExecutable</code> = <code>true</code> Boolean - Whether to sign and add metadata to executable. Advanced option.</li>
<li tag.description=""><code id="WindowsConfiguration-signDlls">signDlls</code> = <code>false</code> Boolean - Whether to sign DLL files. Advanced option. See: <a href="https://github.com/electron-userland/electron-builder/issues/3101#issuecomment-404212384">https://github.com/electron-userland/electron-builder/issues/3101#issuecomment-404212384</a> Deprecated:</li>
<li><code id="WindowsConfiguration-signExts">signExts</code> Array&lt;String&gt; | “undefined” - Explicit file extensions to also sign. Advanced option. See: <a href="https://github.com/electron-userland/electron-builder/issues/7329">https://github.com/electron-userland/electron-builder/issues/7329</a></li>
</ul>
<h2 id="windowsazuresigningconfiguration">WindowsAzureSigningConfiguration</h2>
<p>Also allows custom fields <code>[k: string: string]</code> passed verbatim (case sensitive) to Invoke-TrustedSigning</p>
<ul>
<li>
<p><strong><code id="WindowsAzureSigningConfiguration-endpoint">endpoint</code></strong> String - The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources.</p>
<p>Translates to field: Endpoint</p>
<p>Requires one of environment variable configurations for authenticating to Microsoft Entra ID per <a href="https://learn.microsoft.com/en-us/dotnet/api/azure.identity.environmentcredential?view=azure-dotnet#definition">Microsoft’s documentation</a></p>
</li>
<li>
<p><strong><code id="WindowsAzureSigningConfiguration-certificateProfileName">certificateProfileName</code></strong> String - The Certificate Profile name. Translates to field: CertificateProfileName</p>
</li>
</ul>
<h2 id="windowssigntoolconfiguration">WindowsSigntoolConfiguration</h2>
<p>undefined</p>
<ul>
<li><code id="WindowsSigntoolConfiguration-sign">sign</code> module:app-builder-lib/out/codeSign/windowsSignToolManager.__type | String | “undefined” - The custom function (or path to file or module id) to sign Windows executables</li>
</ul>
<hr>
<ul>
<li><code id="WindowsSigntoolConfiguration-signingHashAlgorithms">signingHashAlgorithms</code> = <code>['sha1', 'sha256']</code> Array&lt;“sha256” | “sha1”&gt; | “undefined” - Array of signing algorithms used. For AppX <code>sha256</code> is always used.</li>
<li><code id="WindowsSigntoolConfiguration-certificateFile">certificateFile</code> String | “undefined” - The path to the *.pfx certificate you want to sign with. Please use it only if you cannot use env variable <code>CSC_LINK</code> (<code>WIN_CSC_LINK</code>) for some reason. Please see <a href="/code-signing">Code Signing</a>.</li>
<li><code id="WindowsSigntoolConfiguration-certificatePassword">certificatePassword</code> String | “undefined” - The password to the certificate provided in <code>certificateFile</code>. Please use it only if you cannot use env variable <code>CSC_KEY_PASSWORD</code> (<code>WIN_CSC_KEY_PASSWORD</code>) for some reason. Please see <a href="/code-signing">Code Signing</a>.</li>
<li><code id="WindowsSigntoolConfiguration-certificateSubjectName">certificateSubjectName</code> String | “undefined” - The name of the subject of the signing certificate, which is often labeled with the field name <code>issued to</code>. Required only for EV Code Signing and works only on Windows (or on macOS if <a href="https://www.parallels.com/products/desktop/">Parallels Desktop</a> Windows 10 virtual machines exits).</li>
<li><code id="WindowsSigntoolConfiguration-certificateSha1">certificateSha1</code> String | “undefined” - The SHA1 hash of the signing certificate. The SHA1 hash is commonly specified when multiple certificates satisfy the criteria specified by the remaining switches. Works only on Windows (or on macOS if <a href="https://www.parallels.com/products/desktop/">Parallels Desktop</a> Windows 10 virtual machines exits).</li>
<li><code id="WindowsSigntoolConfiguration-additionalCertificateFile">additionalCertificateFile</code> String | “undefined” - The path to an additional certificate file you want to add to the signature block.</li>
<li><code id="WindowsSigntoolConfiguration-rfc3161TimeStampServer">rfc3161TimeStampServer</code> = <code>http://timestamp.digicert.com</code> String | “undefined” - The URL of the RFC 3161 time stamp server.</li>
<li><code id="WindowsSigntoolConfiguration-timeStampServer">timeStampServer</code> = <code>http://timestamp.digicert.com</code> String | “undefined” - The URL of the time stamp server.</li>
</ul>
<hr>
<ul>
<li><code id="WindowsSigntoolConfiguration-publisherName">publisherName</code> String | Array&lt;String&gt; | “undefined” - <a href="https://github.com/electron-userland/electron-builder/issues/1187#issuecomment-278972073">The publisher name</a>, exactly as in your code signed certificate. Several names can be provided. Defaults to common name from your code signing certificate.</li>
</ul>

<!-- end of generated block -->

Expand Down
2 changes: 1 addition & 1 deletion packages/app-builder-lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"async-exit-hook": "^2.0.1",
"bluebird-lst": "^1.0.9",
"builder-util": "workspace:^25",
"builder-util-runtime": "workspace:^9",
"builder-util-runtime": "workspace:*",
"chromium-pickle-js": "^0.2.0",
"config-file-ts": "0.2.8-rc1",
"debug": "^4.3.4",
Expand Down
Loading

0 comments on commit d50d563

Please sign in to comment.