How does Sonoma check an app before launch?

Most major versions of macOS bring changes to the checks made on apps before they can be launched, and Sonoma is no exception. In the light of Apple’s newly revised Platform Security Guide, and some light reading of logs, this article tries to outline how this works in Sonoma 14.4.1 for a third-party app that is correctly signed and notarized by Apple.

As launching an app these days can generate thousands of log entries in a matter of a few seconds, and there are many different scenarios and variations, this account concentrates on broad principles and skips many details. Prominent and loquacious sub-systems such as TCC and RunningBoard are largely glossed over, in an effort to tell the wood from thousands of trees.

Major features involved include:

  • Quarantine
  • LaunchServices database
  • CDHashes in the app’s signature and notarization ticket
  • App translocation
  • Gatekeeper assessment
  • XProtect direct malware and dylib scan
  • App first launch prompt
  • Provenance data.

Main features

Quarantine is set in an extended attribute attached to an app’s folder and contents. When an app is downloaded from the Internet, or transferred between Macs using AirDrop, the app responsible for transfer normally attaches an extended attribute of type com.apple.quarantine, within which is a flag indicating that quarantine is set. Apps that unarchive formats such as Zip normally propagate quarantine extended attributes to all the files they generate. Thus, the presence of a com.apple.quarantine extended attribute is a good indicator of external origin, as a result of which LaunchServices treats the app bundle as untrusted.

LaunchServices maintains a database of all app bundles that it has launched, and have thus become known to it. When an app is already detailed in one of the records in that database, the information provided is normally sufficient for its bundle to be trusted, and its checking and launch will be shortened.

As part of the process of signing an app, hashes are created for its components, and these are hashed again to form a tree of CDHashes. Sonoma uses these to check the integrity of each part of an app, by comparing freshly calculated hashes against values saved in its cache of CDHashes. Notarization tickets also consist of CDHashes, and those are compared against Apple’s records over a CloudKit connection to verify that app’s notarization status.

If a quarantined app is run from the same folder that it was first created in, that’s detected by macOS, and is normally an indication that, before it can be checked and launched, that app will be copied to a hidden folder in an unpredictable path such as /private/var/folders/x4/[random]/T/AppTranslocation/[UUID]/d/, a process known as app translocation. This can normally be avoided simply by moving the app into an Applications folder before launching it for the first time.

Gatekeeper assessments are now performed on all apps and executable code even if they’re not quarantined, although those run on code that has already been evaluated are briefer, and may consist only of checks on CDHashes without looking up the notarization ticket remotely or scanning by XProtect.

XProtect in this case refers to the on-demand check for malware against the set of static rules kept in the XProtect bundle. Those are intended to detect known malicious software, and are updated at frequent intervals. They’re different from the daily background scans performed to detect and remediate malware by XProtect Remediator, and from the third and latest form of XProtect that monitors suspicious behaviour.

When a notarized app is run for the first time and is quarantined, macOS asks the user to give their explicit consent in a dialog shown once checks have confirmed that it’s safe to run.

Later versions of macOS Ventura added a new database that tracks all apps that have been quarantined, using another extended attribute, of type com.apple.provenance. The purpose of this isn’t fully understood yet, but it may be related to the new behavioural variant of XProtect.

Check sequence

This is summarised in the simplified diagram below, derived from tracing these checks being made on several different apps, ranging from a well-known app that has been run frequently out of quarantine, to quarantined apps run in their original location and when moved into the /Applications folder.

LaunchSonomaApp1

A PDF version is available from here: LaunchSonomaApp1

The first two steps establish whether the app is already known and approved, and can be fast-tracked, or needs to be treated as untrusted and subject to more extensive assessments. That depends on whether the app is quarantined, and whether it’s already in LaunchServices’ database.

The fast track still brings a Gatekeeper assessment in every case, but when the code has already been evaluated and its CDHashes have been cached, and match, the app can be launched by RunningBoard within 0.1 seconds.

At the other extreme is an app that is unknown to LaunchServices (and its CDHashes aren’t cached), and is in quarantine. Before its Gatekeeper assessment takes place, CDHashes are copied for checking later, and the decision made whether to translocate it, if it’s being run from its original folder. It’s important to note that this isn’t the full path that’s checked: if a quarantined app arrives in a folder named Extras and that folder is moved to an Applications folder, then translocation is still expected.

Gatekeeper assessments then include a direct on-demand scan by XProtect for malware and dylibs, which may be deferred when the app is running in translocation. If those checks are completed successfully, then the user is prompted to decide whether to continue and launch the app. Only after code evaluation has been completed successfully are details of the app added to the provenance database. Typical time from the start of checks to the user prompt is around 0.5 seconds when all goes well.

Key points

  • All apps and executable code undergo Gatekeeper assessment, including CDHash checks.
  • XProtect malware and dylib scans are performed on all quarantined apps.
  • Online notarization checks via CloudKit are normally made on quarantined apps.
  • If an app is updated or changed so that it no longer matches its entry in the LaunchServices database, or its CDHashes change, then a more extensive Gatekeeper assessment is made, including XProtect scanning.
  • If an app is incorrectly updated or changed so that its CDHashes change but those remain associated with unchanged file inodes, then that should be detected and treated as failure to match the app’s signature.
  • Apps run from the same folder they arrived in are translocated before Gatekeeper assessment.
  • When successful, apps are now launched through RunningBoard rather than LaunchServices.