Distributing Mac apps without notarization

March 7 2021 by Jeff Johnson

Sometimes a developer needs to send a Mac app to a user for testing, and in that case it's a pain to upload the app to App Store Connect first and wait for Apple to notarize the app before you distribute it. Another problem is that notarization requires apps to enable the hardened runtime. As I explained in a previous blog post, sandboxing and the hardened runtime are two independent technologies, and while the App Store requires apps to enable sandboxing, it doesn't require apps to enable the hardened runtime. Thus, if you normally distribute your app exclusively in the Mac App Store, the app might not have enabled the hardened runtime, and you won't be able to notarize the app for distribution outside the Mac App Store, which you may discover to your frustration at the last minute. (Needless to say, TestFlight for Mac doesn't exist yet, sigh.)

The good news is that there's a trick to avoiding notarization: macOS doesn't check for notarization unless the app is quarantined. In most cases, a quarantine extended attribute is added to any file downloaded with a web browser, email client, or messaging app. One way to work around the lack of notarization is to remove the quarantine from the download with a Terminal command:

xattr -d com.apple.quarantine ~/Downloads/MyApp.zip

However, Mac experts may know what's coming next:

"Terminal.app" would like to access files in your Downloads folder.

Ah yes, the dreaded permission dialog! By default, Terminal does not have Full Disk Access in the Privacy pane of System Preferences, so you can't count on the user already having access to the Downloads folder in Terminal. You'd have to warn the user about the warning and instruct them that clicking OK is OK.

If you're already going to make the user run a Terminal command, though, why not simultaneously skip both types of built-in macOS "nagware" — Gatekeeper and TCC?

curl https://mysite.com/download/MyApp.zip --output /Applications/MyApp.zip

Unlike web browsers and other apps, curl does not automatically add a quarantine extended attribute to downloads, so it bypasses Gatekeeper. And if curl downloads the file directly to Applications, it also bypasses TCC, which doesn't protect the Applications folder.

In my opinion, using curl in this way is the easiest way to distribute a Mac app to a user without notarization. You still can and should sign your app with your Developer ID certificate, as Mac developers did for years before the notarization requirement. If the user wants some assurance about the downloaded app, they can run the codesign command to verify that the app was indeed validly signed with your Developer ID certificate.

By the way, forgoing the quarantine has the additional benefit of avoiding the problematic Gatekeeper Path Randomization, AKA App Translocation.

Jeff Johnson (My apps, PayPal.Me)