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
44 changes: 41 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,47 @@ run, so releases cannot loop. For a MINOR or MAJOR release, bump the version
yourself (`npm version minor --no-git-tag-version`) and push; the next patch bump
continues from there.

macOS builds are unsigned by default. To sign and notarise, set
`CSC_LINK`/`CSC_KEY_PASSWORD` and the notarisation credentials before running
`npm run dist:mac`.
### Unsigned macOS builds

macOS builds carry no Apple certificate. `electron-builder.yml` sets
`identity: "-"`, and `dist:mac` runs with `CSC_IDENTITY_AUTO_DISCOVERY=false`, so
a certificate sitting in your keychain is never picked up — a build on your
machine is byte-for-byte the same deal as a build in CI.

`"-"` is an *ad-hoc* signature: no identity, no team, nothing Gatekeeper will
accept — but a structurally valid one. That is the part worth having. Skipping
signing altogether leaves the bundle carrying Electron's original signature over
resources electron-builder has since rewritten, which `codesign --verify` fails:

```
code has no resources but signature indicates they must be present
```

A quarantined app in that state is not merely refused — Gatekeeper reports it as
"damaged and can't be opened. You should move it to the Trash", and right-click →
*Open* will not get past it. With a valid ad-hoc signature the same app gets the
ordinary unidentified-developer dialog instead, which right-click → *Open* does
clear.

So the `.app` runs anywhere, but macOS quarantines it the moment it arrives by
download, AirDrop, Slack or email, and an ad-hoc signature does not clear that
quarantine. Whoever you hand the build to has to say so once, either way:

- **Finder** — right-click the app, choose *Open*, then *Open* in the dialog.
On macOS 15 and newer, open it normally first, then allow it under
*System Settings › Privacy & Security*.
- **Terminal** — strip the quarantine flag outright:

```bash
xattr -dr com.apple.quarantine "/Applications/Mongo Explorer.app"
```

Either is needed only once per install, not per launch.

To ship something that skips all of this, sign and notarise properly: set
`CSC_LINK`/`CSC_KEY_PASSWORD` and the notarisation credentials, drop the
`identity` line from `electron-builder.yml`, and set `hardenedRuntime: true`
(notarisation requires it) before running `npm run dist:mac`.

## Verifying

Expand Down
11 changes: 9 additions & 2 deletions electron-builder.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,15 @@ mac:
- target: zip
arch: [arm64, x64]
darkModeSupport: true
# Unsigned local builds: without this macOS refuses to open the .app because
# the hardened runtime has no signature to validate.
# No Apple certificate is ever used. "-" is an ad-hoc signature: it carries no
# identity, so the app stays unsigned as far as Gatekeeper is concerned, but it
# is a *valid* one. Without it the bundle keeps Electron's own signature over
# resources we have since rewritten, and Gatekeeper calls a quarantined copy of
# that "damaged" — which right-click Open cannot clear, unlike an ad-hoc build.
identity: "-"
# The hardened runtime would validate that signature against an identity there
# isn't one of, and gatekeeperAssess would run the build through spctl, which
# by definition rejects anything unsigned.
hardenedRuntime: false
gatekeeperAssess: false
extendInfo:
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"smoke": "node scripts/build-smoke.mjs && node scripts/with-mongod.mjs electron dist/smoke/smoke.js",
"pack": "npm run build && electron-builder --dir",
"dist": "npm run build && electron-builder -mwl",
"dist:mac": "npm run build && electron-builder --mac",
"dist:mac": "npm run build && CSC_IDENTITY_AUTO_DISCOVERY=false electron-builder --mac",
"dist:win": "npm run build && electron-builder --win",
"dist:linux": "npm run build && electron-builder --linux",
"ui-check": "npm run build && node scripts/build-ui-check.mjs && node scripts/with-mongod.mjs electron dist/smoke/ui-check.js",
Expand Down
Loading