Skip to content

feat(desktop): Developer ID signing + notarization for macOS release#3619

Merged
esengine merged 1 commit into
main-v2from
feat/macos-signing
Jun 9, 2026
Merged

feat(desktop): Developer ID signing + notarization for macOS release#3619
esengine merged 1 commit into
main-v2from
feat/macos-signing

Conversation

@esengine

@esengine esengine commented Jun 9, 2026

Copy link
Copy Markdown
Owner

What

Replace the ad-hoc macOS codesign with a real Developer ID Application signature + notarization, so a downloaded desktop build opens with no Gatekeeper "is damaged / unidentified developer" prompt.

Changes

  • scripts/desktop-build.sh — when HAS_APPLE_CERT is set, sign the .app with Developer ID (hardened runtime + entitlements + secure timestamp), notarize the .app and the .dmg via notarytool --wait, then stapler staple the tickets. Without it, fall back to the existing ad-hoc signing.
  • .github/workflows/release-desktop.yml — new macOS-only "Import Apple signing certificate" step (imports the .p12 into a throwaway keychain, stages the .p8 notarization key); the build step derives HAS_APPLE_CERT from the five APPLE_* secrets and injects the notarization env.
  • desktop/build/darwin/entitlements.plist — new. Hardened-runtime entitlements (JIT / unsigned-executable-memory / library-validation carve-outs the Go + WKWebView runtime needs to notarize).
  • desktop/.gitignore — un-ignore the entitlements file. Unlike Info.plist it is not regenerated by wails build, so it must live in git.

Gating / safety

HAS_APPLE_CERT is true only when all five secrets (APPLE_CERT_P12, APPLE_CERT_PASSWORD, APPLE_API_KEY_P8, APPLE_API_KEY_ID, APPLE_API_ISSUER_ID) are present. With none set — forks, local builds — the build ad-hoc signs exactly as before. No behavior change without secrets.

Verification

  • bash -n scripts/desktop-build.sh passes; workflow YAML parses; the ad-hoc fallback path is intact.
  • End-to-end signing + notarization only runs on a desktop-v* tag (or a local HAS_APPLE_CERT=true smoke test); it is not exercised by this PR's CI.

Replace the ad-hoc codesign in desktop-build.sh with a real Developer ID
Application signature (hardened runtime + entitlements + timestamp),
notarize the .app and the .dmg via notarytool, and staple the tickets, so
a downloaded build opens with no Gatekeeper prompt.

Gated on HAS_APPLE_CERT (derived from the APPLE_* secrets in
release-desktop.yml): with no secrets the build falls back to ad-hoc
signing, leaving fork and local builds unaffected. The workflow imports
the cert into a throwaway keychain and stages the notarization key.

Add build/darwin/entitlements.plist (hardened-runtime carve-outs for the
Go + WKWebView runtime) and un-ignore it in desktop/.gitignore, since
unlike Info.plist it is not regenerated by wails build.
@esengine esengine requested a review from SivanCola as a code owner June 9, 2026 02:53
@github-actions github-actions Bot added v2 Go rewrite (1.x) — main-v2 branch, active development desktop Wails desktop app (desktop/**) updater Auto-update / installer / release packaging labels Jun 9, 2026
@esengine esengine merged commit ccbdc79 into main-v2 Jun 9, 2026
11 checks passed
@esengine esengine deleted the feat/macos-signing branch June 9, 2026 06:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

desktop Wails desktop app (desktop/**) updater Auto-update / installer / release packaging v2 Go rewrite (1.x) — main-v2 branch, active development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant