Main navigation

Macs move closer to compulsory notarization

Mojave introduced a new and more stringent form of code-signing, notarization, which has so far been voluntary. Apple stated that at some time in the future it would become a requirement, and that is coming rapidly closer. In preparation, the rules have just changed again: if you are using Mojave, this could start tripping you up, and if you’re a developer you may need to take action very quickly.

Signing past

Code signing has been built into macOS for well over a decade now, but has remained fairly relaxed. When a developer builds an app, the final step is to attach a checksum and digital signature, based on a certificate issued by Apple, in the _CodeSignature folder inside the app. When that app is obtained from the Internet, the app which downloads it (such as your web browser) attaches a quarantine flag; when you then run the app for the first time, macOS detects that flag and puts the app through a full Gatekeeper check, in which its signature is verified.

Although signatures are checked on other occasions, for a wide range of reasons, it is this first run sequence of download, quarantine flag, Gatekeeper checks which is most important. No matter what you might want, if Gatekeeper finds something wrong with that signature, you can’t open that app (without performing surgery on it). But once an app has passed its first run check, it will open normally even if that signature becomes damaged or removed, or the app is tampered with.

Notarization future

Notarization changes this in several ways.

Most importantly, no one can notarize their own app, only Apple can. Developers upload their apps to Apple for notarization, and that involves checking the app meets more stringent criteria and undergoing automated testing for evidence of malicious behaviour. For the last couple of years, most malware for macOS has been correctly signed using valid developer certificates. Apple’s testing routines are intended to prevent malware from being notarized, thus give you better confidence that a new app isn’t going to be bad news.

In order for an app to be successfully notarized, it must also be hardened, which restricts its behaviours. Hardening applies a set of rules which are not unlike those applied to App Store apps. For example, if a hardened app wants to access your address book, it has to declare that when it’s built, provide an explanation which you will be given, and then pass through standard privacy checks when you first run it.

Hardening doesn’t ban potentially harmful behaviours like executing JIT-compiled code, but they are only allowed if the app declares them prior to notarization. Most importantly for many notarized apps, they aren’t run in a sandbox in the way that App Store apps are required to be, so the requirements of hardening should seldom if ever get in the way of the app or its user.

Notarization is specific to that release of that particular app. If there is a problem with that version, Apple can revoke notarization for that alone. Using developer certificates, Apple can only revoke the certificate, which blocks all subsequent first runs on any app of any version signed using the same developer certificate.

When Apple makes notarization of apps mandatory, any app which is to pass through first run checks and has been downloaded from the Internet will have to be notarized (or be from the App Store), or Gatekeeper simply won’t allow it to run. This brings major change to the way in which we supply, obtain, and install apps.

What changes

If you’re still running High Sierra or earlier, notarization doesn’t apply. As far as your older version of macOS is concerned, a notarized app is just ordinarily signed. Notarization also only applies at first run, when an app undergoes its full Gatekeeper check. Once the quarantine flag has been cleared, a notarized app doesn’t undergo any further checks of that stringency. However, the restrictions imposed by hardening do still apply, so the app can’t suddenly modify itself to break the rules set by its hardening.

From the first release of Mojave, the only noticeable difference with notarized apps has been the slightly different dialog which appears when they are first run, telling you that they have undergone checking by Apple. From Mojave 10.14.5, this is going to change.

First, all new or updated kernel extensions (KEXTs) are going to require notarization. This is unlikely to affect many users, though, as kernel extensions already require special certificates and aren’t exactly commonplace anyway. But if a developer releases software containing a kernel extension which has been updated in any way, and they fail to get it notarized, it will break in 10.14.5 and later.

Second, any developers who join Apple’s developer programme from now on won’t be able to release apps using their normal developer certificate alone, but will have to notarize all their apps from the start. Developers who have already released apps using their existing developer certificate(s) aren’t affected by this, though. This again is unlikely to have much impact in itself.

More important, though, is Apple’s warning: “In a future version of macOS, notarization will be required by default for all software.” As the next major release is expected to be macOS 10.15 in the autumn/fall, that looks the most likely time of introduction.

Because notarization is only going to be required at first run (unless Apple makes very major and unexpected changes), this doesn’t affect the apps that you already have installed. If they have passed through their Gatekeeper check and the quarantine flag has been cleared, existing apps should still run fine.

But when you upgrade to 10.15, in addition to losing access to all your old 32-bit apps, you should expect that the only apps which complete first run checks successfully are those which have been notarized, or are obtained from the App Store. If you try opening a freshly downloaded app which hasn’t been notarized, you should expect it to be rejected by Gatekeeper, and you’ll be blocked from running it in 10.15.

Uncertainties

As ever, life isn’t quite as simple as Apple’s announcement might seem. It doesn’t, for example, address problems with command tools, which currently don’t pass through Gatekeeper checks, and are often unsigned, although it is possible to attach signatures to them. Apple still doesn’t have a scheme to provide an equivalent to notarization for command tools which aren’t embedded in an app or other code bundle. If you distribute your command tool as part of an Installer package, it is supposed to be possible to get the whole package notarized, although Apple hasn’t detailed a workflow for doing that, nor said whether all installer packages will be required to be notarized. Hopefully some time before 10.15 is released this will become clearer.

For the moment, then, the changes coming in 10.14.5 with respect to notarization are likely to have no impact on the great majority of Mac users. But they are the shape of things to come surprisingly soon. If you develop macOS software which is distributed online, you need to get into notarization as a matter of urgency.

Key points

Notarization only affects Macs running Mojave, and these changes only apply to version 10.14.5 and later.

Notarization is only checked when you first run an app which has been downloaded from the Internet and has gained a quarantine flag as a result.

None of this affects your existing apps, provided that they have already been run, even if migrated from an older Mac.

This affects apps and executable code bundles, including kernel extensions, but not command tools, nor apps installed from the App Store.

This also affects updates to existing apps and kernel extensions which are downloaded from the Internet.

Finally, how can you check whether an app is notarized? This has been a feature of my drag-and-drop utility Taccy since Mojave was released last year. It’s free, of course, and available from here and from Downloads above.

20Comments

About once per month I run Onyx (https://www.titanium-software.fr/en/onyx.html) on my system to give it a bit of a cleanup. Part of that cleanup is rebuilding the Launch Services database. When I open many (but not all?) applications after having done that, I’m once again presented with the GateKeeper dialog for that application. I guess I might be in trouble with older un-notarised applications after I’ve installed macOS 10.15.

That sounds like a serious bug in OnyX.
Rebuilding the Launch Services database every month seems to be inviting trouble. However, that shouldn’t be causing this problem. Something is altering the quarantine flags on those apps – if that’s OnyX, then you shouldn’t be doing that. This is one of the problems of ‘cleaning apps’, however well-intentioned, they do things behind your back which cause more problems than they solve. macOS doesn’t need that sort of cleaning up unless there are problems.
Howard.

“Using developer certificates, Apple can only revoke the certificate, which blocks all subsequent first runs on any app of any version signed using the same developer certificate.”

This is actually not true. It’s exactly why Xcode uses a secure timestamp (codesign flag –timestamp) when signing a release build. With the secure timestamp, the system can block versions built when the certificate was known to be compromised, for example, while not blocking other versions from when the cert was known to be not compromised.

“Once the quarantine flag has been cleared, a notarized app doesn’t undergo any further checks of that stringency. However, the restrictions imposed by hardening do still apply, so the app can’t suddenly modify itself to break the rules set by its hardening.”

A non-sandboxed app can modify itself and indeed has to in order to software update itself.

Thank you, Jeff.
Although revocation can be made time-specific, it remains a blunt tool which applies to all apps of all versions made after such a specified time. As you know, this is the argument put by Apple, which is the authority controlling certificates and revocation. Does Apple issue such revocations limited by timestamp, I wonder?
Your second point about self-modifying code implies that the hardening flags are worthless in that respect. I’d be interested to see an example of a hardened app which modifies itself after passing through Gatekeeper’s checks to operate beyond the entitlements set in its certificate by the hardening settings.
Howard.

Yes, Apple issues revocations based on timestamp. Just look at the case of Panic. Their signing cert was compromised: https://panic.com/blog/stolen-source-code/
Yet older versions of the apps can still be downloaded and work: https://download.panic.com/
That’s because there are secure timestamps, and they know when the cert was compromised. Yes revocation applies to all apps of all versions made after a specified time, because that’s exactly the point. Once a signing cert gets into the hands of a bad actor, you can’t trust anything signed with that cert after that point. Notarization is not going to improve the situation at all in that respect. Apple could revoke a very specific version of one app, but… if there’s a malware version validly signed with DevID, that means the cert itself has been compromised, so it’s the same problem as before.

As for apps modifying themselves, as I suggested already, any app outside the App Store with built-in software update can modify itself. The point of the hardened runtime is not to protect the user from a malware app. A non-sandboxed malware app is going to get you no matter what. The point of the hardened runtime is to protect a legitimate app from getting exploited by malware from elsewhere. Just look at the nature of the hardened runtime protections: they’re not protecting the user environment, they’re protecting the app’s own environment.

(I’m having to take these one at a time, as I’m also trying to write a review, and running out of threads!)
If you only consider the event of total certificate compromise, then all you need is a binary system. But there are lots of things that can’t cater for. Compromise isn’t always total, and there are plenty of occasions when we as developers might want a specific version of a specific app pulled.
In the App Store, that’s easy, as there’s no other legit means of distribution. Outside, copies can find themselves onto servers all over the world. Let’s say that MyApp 13 has a serious bug. How can I stop new users from downloading and running it? Revoke my developer certificate? No – that would be far too disruptive. Notarization can deal with this fine, of course: Apple can (we all hope!) revoke that specific version of that product – something which could also be appropriate in some cases of limited compromise.
As we both know, Apple often makes changes which only make deep sense a bit further down the line. At present, the only time macOS does anything about invalid or revoked certificates is during Gatekeeper checks. As we’ve discussed here before, it’s pretty bad when macOS will happily let an app have access to some very sensitive resources, even keychains perhaps, when it knows the signature isn’t valid. But you’re stuck with that when you only have a coarse-grained binary control. Maybe in the future, we’ll see signature failures being treated more seriously when macOS is asked to give access to sensitive areas and data. At least it would be feasible.
Howard.

I don’t know, Mark.
As you know, apps which update using Sparkle have an in-bundle app which downloads and assembles the update app around itself. In traditional signing, that updater sometimes isn’t even signed, but it still seems to clear through Gatekeeper’s checks.
I’m not aware of any of the notarized apps that I have here which use Sparkle, so haven’t knowingly tried it.
I’ll be interested to hear from a developer who has notarized an app which does use Sparkler for updates, as to how that works.
If Jeff’s contention that an app can modify itself is correct, then there shouldn’t be any problem. Perhaps Sparkle is a test case, although it shouldn’t ordinarily result in any change in the hardening settings, of course.
Howard.

Thank you – that is valuable information. I had heard of the problems with app translocation, but wasn’t sure how the Sparkle system would cope with updating a notarized app without breaking that notarization.
Howard.

I tired to notarize an AppleScript using the method that Rich Trouton posted at Der Flounder for his own Automator app. The code-signing and the notarization steps went exactly as planned but I was not able to staple the valid notarization to the signed AppleScript app.
I hope AppleScript will not be left behind on this new evolution.

I haven’t heard back about the bug report but in the meantime…
Instead of creating a .zip, I created a .dmg and then signed it (without hardening)
I used the signed .dmg to upload for notarization and was then able to staple the successful notarization to the .dmg.
So maybe that is the way to deal with AppleScript apps.

Thanks.
This is because of the sudden and unexpected introduction of the requirement for KEXTs to be notarized. Where an app depends on a KEXT for its function, that app will be broken.
Such are the joys of beta-testing and, indeed, developing for macOS. Apple gave developers no notice of this change whatsoever.
Howard.