Opening an app has become significantly more complex in macOS Mojave than it was in High Sierra, Sierra, or El Capitan. Each major release of macOS has brought substantial changes to the process: app translocation, more Gatekeeper and XProtect checks, and in Mojave the controls enforced by its privacy manager, TCC.
This article draws comparison between what is written to the log when you open a regular developer-signed app in Sierra and Mojave, and how a new ‘notarized’ app works too. In each case, I added a quarantine extended attribute to the app before opening it, to simulate what happens when the app has been freshly downloaded from the internet. This drives macOS to perform its fullest assessment of the app before it allows it to run.
In each of these log summaries, the clock time is given in blue at the start of the entry, following which the subsystem is shown in red. The remainder of the entry, shown in black, is the eventMessage. These are inevitably select highlights from thousands of entries over the time periods shown.
In macOS 10.12 Sierra, opening an app works the way that you probably think it should. The initial log entry, sendAction:, is part of the double-click to open the app. The app is then translocated into a specially-created folder to be run from there, as it is running for the first time with a quarantine xattr.
Then follows a Gatekeeper check, and assessment by XProtect. As the app has a valid developer signature and doesn’t match any of XProtect’s criteria for supposing that it is malware, its launch is allowed to proceed. This takes it on to the dialog in which the user is asked to confirm that they want to open the app.
The initial checking steps here take less than 0.5 seconds from first click to accepting the app as wholesome.
A regular signed app launched in macOS 10.14 Mojave appears quite different, although some of this is due to changed practices and policies for writing to the log. Once again, an early action is to translocate the app to a special folder, where XProtect performs its security assessment before running a malware scan on it. This initial security assessment takes just over 0.5 seconds, during which its signature is checked. As this is a first run in quarantine, this should include a deep check of the signature against blacklists.
When those are complete, LaunchServices is allowed to proceed with launching the app, but TCC, concerned with privacy protection, then runs its own assessment. Significantly, this includes checking which version of the SDK it was built against, which determines whether TCC’s strict new policies are applicable. In this case, the SDK version is 10.14 (hex 0a0d00), so this app will only be allowed to access protected data and services for which it has usage information strings in its Info.plist. As it isn’t hardened or notarized, it doesn’t have entitlements.
What I haven’t included here is the succession of errors when trying to check whether this app is notarized. In this case, it is because it is not, just signed in the ordinary way with a Developer ID.
Total time from first click to LaunchServices being allowed to proceed is here around 3 seconds, although this Mac is much faster than that running Sierra.
This is my app xattred, which is built against the 10.14 SDK, hardened and notarized, and has entitlements and usage information strings to support access to most protected data classes. It too is translocated to and run from a special folder.
Note that the XProtect security assessment here takes over 4 seconds, which includes time spent checking it not just against local databases, but verifying its notarization. LaunchServices then relocates its bundle and execution paths after a further delay of over 2 seconds, during which additional checks are made.
When TCC starts work on it, it still referred to it in its translocation folder, and is run from there. TCC knows that its runtime has been hardened, and applies the prompting policy appropriate to that, rather than just a Developer ID. This requires matching the entitlements which have been baked into its signature with the usage strings in its Info.plist. To be able to access any protected data, it requires both the appropriate entitlement and a usage string for that class of data.
The final entry given there (and for the previous app) is fascinating, but inexplicable without further knowledge of how TCC works. It refers to deriving a “team id” for the app for that given user ID. Presumably the outputs from these steps in TCC are stored in its database, ready for use when the app tries to access protected data or services.
Total time from first click to LaunchServices proceeding is now around 7 seconds, on the same Mac used for the previous Mojave test.
It is also worth bearing in mind that apps are normally only run once with their quarantine xattrs set. Subsequent launches undergo much briefer signature checks of integrity alone.
Updated 1640 3 October 2018 following helpful information from @lapcatsoftware pointing out that, although LaunchServices may relocate the bundle and exec paths during this initial run of an app in quarantine, the app is still actually run from translocation. On more thorough search of the logs from a non-notarized app, they behave just the same in Mojave, so this is not peculiar to apps which have been notarized.