Search code examples
xcodemacoscertificatecode-signingapple-developer

How to properly sign a Mac application for self-distribution?


I created a Mac file upload client application that implements a high-performance reliable data transfer over UDP protocol, based on the UDT library.

My setup:

  • MacOS Mojave
  • Xcode 10.3
  • Deployment Target: 10.10 (minimum for storyboard-based forms)

Now I'm trying to figure out how to sign it properly so end users can run it without doing a Gatekeeper override.

Here's where I'm at:

  • I have a paid Apple Developer account, delegated to me from an organization paid Developer account
  • I have roles assigned to me allowing me to manage apps, certificates, provisioning, etc.
  • I am signed into this account under Xcode accounts under Preferences.
  • I have created a bundle registration under the account, copied exactly from Xcode
  • I have created a Mac Distribution certificate, starting with a CSR from my development machine.
  • I have downloaded and imported the certificate into my machine's keychain (listed as "3rd Party Mac Developer Application:...")
  • I have created a provisioning profile for this app, with above certificate assigned, the profile type is App Store, but I will be distributing the app myself (is there a more correct provisioning type?)
  • Under Entitlements I chose "Custom Network Protocol", which sounds like an accurate description of my application.
  • I have imported the provisioning profile into Xcode and chose it under Signing (Debug) and Signing (Release) of my project's target, it automatically populated Team (the parent organization) and the above certificate.
  • I changed the scheme in the project to "Release" and built it for "Running", I get a keychain access prompt during build, and signing step completes successfully
  • codesign -vvv -d xyz.app returns the registered bundle, certificate, team, etc, all matching the above choices.
  • I placed the produced .app into a .dmg image and emailed it to myself
  • I downloaded the .dmg on another Mac and mounted it
  • I tried running the .app but got the following Gatekeeper message:

"XYZ" can't be opened because it is from an unindentified developer. Your security preferences allow installation of only apps from the App Store and identified developers.

How do I get around this so a downloaded application will have an "Open" button in the Gatekeeper prompt by default. Some applications, GIMP for example, are correctly identified, even though they did not originate from the App Store.

What do I need to to resolve this?


Solution

  • I kept digging at it and I found my answer: https://developer.apple.com/documentation/xcode/notarizing_macos_software_before_distribution?language=objc

    The type if certificate I needed was Developer ID and the type of provision Developer ID Application, which is what is intended for self-distribution of a signed Mac application. After that it needs to be submitted to Apple for notarization to satisfy the requirement for 10.14.5+. After notarization had completed I was able to send the exported app to myself and it offered me an "Open" option for the app downloaded from Internet. This is the desired behavior.

    It required me to request the account holder to issue me the Developer ID certificate by sending them a CSR, as Developer ID certificate option is greyed out for delegated users that are not the original developer account holder (admin role may satisfy, but I am not one so can't say).

    Yay.