SUZENT / Docs
THE SUZENT HANDBOOK

macOS release signing

The desktop workflow publishes raw Mach-O executables for the main app and the installer. Both must be signed with a Developer ID Application certificate, with hardened runtime and

The desktop workflow publishes raw Mach-O executables for the main app and the installer. Both must be signed with a Developer ID Application certificate, with hardened runtime and a secure timestamp, and accepted by Apple's notary service before upload. An iOS Apple Distribution certificate does not work here.

The desktop build uses the existing mobile-release GitHub environment to share the Apple notarization credentials with iOS. Configure these environment secrets:

SecretValue
MACOS_CERTIFICATE_BASE64Base64-encoded .p12 export containing the Developer ID Application certificate and private key
MACOS_CERTIFICATE_PASSWORDPassword for that .p12 export
APP_STORE_CONNECT_KEY_BASE64Base64-encoded App Store Connect API private key (.p8), shared with iOS
APP_STORE_CONNECT_KEY_IDAPI key ID
APP_STORE_CONNECT_ISSUER_IDAPI key issuer ID

Configure this variable in the same environment:

VariableValue
MACOS_SIGNING_IDENTITYFull identity, such as Developer ID Application: Example (TEAMID)

scripts/sign-macos-release.sh imports the certificate into a temporary keychain, signs both executables, submits a ZIP to notarytool, requires Accepted, and checks each executable with codesign -R="notarized" --check-notarization. spctl --assess targets app bundles and is not suitable for these raw executables. It restores the keychain search list and removes the temporary credentials on exit. Missing credentials or verification failures prevent the build from publishing its assets.

Raw executables cannot have a notarization ticket stapled to them. Gatekeeper needs network access to retrieve their tickets. An offline-friendly release would need a stapled app bundle, DMG, or installer package.

These changes apply to newly built assets. Rebuild an affected release with .release-assets-mode set to build; reuse preserves the previous binaries, including their signing status. Published releases cannot be rebuilt by this workflow: prepare a new patch release to replace an unsigned published version.

See Apple's notarization requirements.

Verify existing assets

Dispatch Build and Publish Desktop Release with an existing desktop tag and verify_signing=true. This path verifies the published checksums, signs and notarizes the existing Intel and Apple Silicon binaries, then uploads signed-macos-* tar archives as Actions artifacts for seven days. It does not modify the GitHub Release. This also allows validation from a workflow branch before merging the signing changes.

The verification job preserves the signed archive before waiting for Apple and uploads it even when notarization times out or fails. An artifact alone is not proof of notarization. Before distributing a preserved candidate, require codesign --verify --strict -R="notarized" --check-notarization to succeed for every executable. Do not re-sign the preserved files: doing so changes the code signature and requires a new notarization submission.

Edit this page on GitHub ↗

On this page