Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/tame-radios-pump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"app-builder-lib": patch
---

fix(mac): allow ad-hoc identities for codesigning
4 changes: 2 additions & 2 deletions packages/app-builder-lib/scheme.json
Original file line number Diff line number Diff line change
Expand Up @@ -2702,7 +2702,7 @@
]
},
"identity": {
"description": "The name of certificate to use when signing. Consider using environment variables [CSC_LINK or CSC_NAME](./code-signing.md) instead of specifying this option.\nMAS installer identity is specified in the [mas](./mas.md).",
"description": "The name of certificate to use when signing. Consider using environment variables [CSC_LINK or CSC_NAME](./code-signing.md) instead of specifying this option.\nMAS installer identity is specified in the [mas](./mas.md).\n\nSet to `-` to use an ad-hoc identity for signing. Set to `null` to skip signing entirely.",
"type": [
"null",
"string"
Expand Down Expand Up @@ -3334,7 +3334,7 @@
]
},
"identity": {
"description": "The name of certificate to use when signing. Consider using environment variables [CSC_LINK or CSC_NAME](./code-signing.md) instead of specifying this option.\nMAS installer identity is specified in the [mas](./mas.md).",
"description": "The name of certificate to use when signing. Consider using environment variables [CSC_LINK or CSC_NAME](./code-signing.md) instead of specifying this option.\nMAS installer identity is specified in the [mas](./mas.md).\n\nSet to `-` to use an ad-hoc identity for signing. Set to `null` to skip signing entirely.",
"type": [
"null",
"string"
Expand Down
5 changes: 3 additions & 2 deletions packages/app-builder-lib/src/codeSign/macCodeSign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,11 @@ export async function reportError(isMas: boolean, certificateTypes: CertType[],
.join("\n")
}

const skipMessage = "skipped macOS application code signing"
if (isMas || isForceCodeSigning) {
throw new Error(Logger.createMessage("skipped macOS application code signing", logFields, "error", it => it))
throw new Error(Logger.createMessage(skipMessage, logFields, "error", it => it))
} else {
log.warn(logFields, "skipped macOS application code signing")
log.warn(logFields, skipMessage)
}
}

Expand Down
19 changes: 15 additions & 4 deletions packages/app-builder-lib/src/macPackager.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { notarize } from "@electron/notarize"
import { NotarizeOptionsNotaryTool, NotaryToolKeychainCredentials } from "@electron/notarize/lib/types"
import { PerFileSignOptions, SignOptions } from "@electron/osx-sign/dist/cjs/types"
import { Identity } from "@electron/osx-sign/dist/cjs/util-identities"
import { Arch, AsyncTaskManager, copyFile, deepAssign, exec, getArchSuffix, InvalidConfigurationError, log, orIfFileNotExist, statOrNull, unlinkIfExists, use } from "builder-util"
import { MemoLazy, Nullish } from "builder-util-runtime"
import * as fs from "fs/promises"
import { mkdir, readdir } from "fs/promises"
import { Lazy } from "lazy-val"
import * as path from "path"
import { AppInfo } from "./appInfo"
import { CertType, CodeSigningInfo, createKeychain, CreateKeychainOptions, findIdentity, Identity, isSignAllowed, removeKeychain, reportError, sign } from "./codeSign/macCodeSign"
import { CertType, CodeSigningInfo, createKeychain, CreateKeychainOptions, findIdentity, isSignAllowed, removeKeychain, reportError, sign } from "./codeSign/macCodeSign"
import { DIR_TARGET, Platform, Target } from "./core"
import { AfterPackContext, ElectronPlatformName } from "./index"
import { MacConfiguration, MasConfiguration } from "./options/macOptions"
Expand Down Expand Up @@ -229,20 +230,24 @@ export class MacPackager extends PlatformPackager<MacConfiguration> {
}
}

private async sign(appPath: string, outDir: string | null, masOptions: MasConfiguration | null, arch: Arch | null): Promise<boolean> {
private async sign(appPath: string, outDir: string | null, masOptions: MasConfiguration | null, arch: Arch): Promise<boolean> {
if (!isSignAllowed()) {
return false
}

const isMas = masOptions != null
const options = masOptions == null ? this.platformSpecificBuildOptions : masOptions
const qualifier = options.identity
const fallBackToAdhoc = (arch === Arch.arm64 || arch === Arch.universal) && !this.forceCodeSigning

if (qualifier === null) {
if (this.forceCodeSigning) {
throw new InvalidConfigurationError("identity explicitly is set to null, but forceCodeSigning is set to true")
}
log.info({ reason: "identity explicitly is set to null" }, "skipped macOS code signing")
if (fallBackToAdhoc) {
log.warn("arm64 requires signing, but identity is set to null and signing is being skipped")
}
return false
}

Expand All @@ -268,7 +273,13 @@ export class MacPackager extends PlatformPackager<MacConfiguration> {
}
}

if (!options.sign && identity == null) {
const noIdentity = !options.sign && identity == null
if (qualifier === "-") {
identity = new Identity("-", undefined)
} else if (noIdentity && fallBackToAdhoc) {
log.warn(null, "falling back to ad-hoc signature for macOS application code signing")
identity = new Identity("-", undefined)
} else if (noIdentity) {
await reportError(isMas, certificateTypes, qualifier, keychainFile, this.forceCodeSigning)
return false
}
Comment thread
mmaietta marked this conversation as resolved.
Expand Down Expand Up @@ -514,7 +525,7 @@ export class MacPackager extends PlatformPackager<MacConfiguration> {
await Promise.all(
directories.map(async (file: string) => {
if (shouldSign(file)) {
await this.sign(path.join(sourceDirectory, file), null, null, null)
await this.sign(path.join(sourceDirectory, file), null, null, packContext.arch)
}
})
)
Expand Down
2 changes: 2 additions & 0 deletions packages/app-builder-lib/src/options/macOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export interface MacConfiguration extends PlatformSpecificBuildOptions {
/**
* The name of certificate to use when signing. Consider using environment variables [CSC_LINK or CSC_NAME](./code-signing.md) instead of specifying this option.
* MAS installer identity is specified in the [mas](./mas.md).
*
* Set to `-` to use an ad-hoc identity for signing. Set to `null` to skip signing entirely.
*/
readonly identity?: string | null

Expand Down
4 changes: 2 additions & 2 deletions pages/code-signing-mac.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
macOS code signing is supported. If the configuration values are provided correctly in your package.json, then signing should be automatically executed.

On a macOS development machine, a valid and appropriate identity from your keychain will be automatically used.
On a macOS development machine, a valid and appropriate identity from your keychain will be automatically used. If no such identity exists, the default behavior depends on the target architecture. On ARM or universal builds, an ad-hoc signature will be applied by default. On Intel-only builds, the default behavior is to not sign at all.

!!! tip
See article [Notarizing your Electron application](https://kilianvalkhof.com/2019/electron/notarizing-your-electron-application/).
Expand All @@ -23,7 +23,7 @@ On a macOS development machine, a valid and appropriate identity from your keych

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`.
Another way — set `mac.identity` to `null`. You can pass additional configuration using CLI as well: `-c.mac.identity=null`. If you are building for ARM, you likely actually want to use ad-hoc signing, in which case you should set `mac.identity` to `-`.

## Code Signing and Notarization Tutorial
Thank you to a community member for putting this together.
Expand Down