App Store apps can be translocated

Since it was introduced in macOS Sierra, the rules determining whether a newly installed app is translocated by Gatekeeper to be launched from a randomized, read-only location have remained ill-defined. However, it has been assumed that three classes of app are invariably exempt:

Apple’s own apps, whether bundled, installed from the installers it provides, or through the App Store;
apps installed by the user dragging them from a signed disk image to local storage;
third-party apps supplied through the App Store.

This article demonstrates that the last of those isn’t necessarily true, and what happens when an App Store app ends up being translocated. My example here is the UTM app, although there’s nothing to indicate this should apply specifically to that. It’s also a useful example, as there’s a notarized version of the app available direct from its website, as well as the App Store version.

An app will be translocated if all the following apply:

the app has an apple.com.quarantine extended attribute attached;
the app must be opened by Launch Services (normally the Finder) rather than a command shell;
the app hasn’t been individually moved in the Finder from the folder it was unarchived or downloaded to, wherever that was.

Website installation

UTM is supplied direct in a signed disk image. Following downloading, the disk image was opened and the app dragged to the main Applications folder. Version 4.5.2 (97) is sandboxed, signed by its Developer ID Application certificate, and notarized.

On arrival, it had a single extended attribute (xattr) of com.apple.quarantine, putting it into quarantine following its download by Safari.

When first launched from /Applications, the launch confirmation dialog was shown, and launch proceeded without translocation, as seen in these excerpts from entries in the log by LaunchServices:
LAUNCH: Successful launched 0x0-0x76076 pid=2918 com.utmapp.UTM (quarantined) ‘<private>’
notifying server side, pid=2918 appInfo={ “ApplicationType”=”Foreground”, , “CFBundleExecutablePath”=”/Applications/UTM.app/Contents/MacOS/UTM”, , “CFBundleExecutablePathDeviceID”=16777233, , “CFBundleExecutablePathINode”=27692383, , […]
QUARANTINE: Setting risk category to LSRiskCategoryUnsafeExecutable

This installation of UTM was therefore spared from translocation because it had been individually moved in the Finder to a different folder, so failing to satisfy the last of the three conditions.

That version of UTM was then trashed.

App Store installation

A previously purchased fresh copy of UTM was downloaded from the App Store, which was installed straight into the /Applications folder by the App Store app. This had the same version number, but was a single build increment higher. As it came from the App Store, it was signed by Apple, and not notarized.

On arrival, it had five xattrs, of which four (com.apple.appstore. series) are common to all App Store apps. The fifth was a surprise, though, as it was a com.apple.quarantine xattr claiming that the app had been downloaded by Safari, which it hadn’t.

When first launched from /Applications, no confirmation dialog was shown, and the app was translocated, as reported by LaunchServices in the log:
LAUNCH: translocate to <private> from <private>
notifying server side, pid=2958 appInfo={ “ApplicationType”=”Foreground”, , “CFBundleExecutablePath”=”/private/var/folders/x4/x00kny5x0_5dsnmmxhtw6hc80000gn/T/AppTranslocation/8130B3C3-BA58-491D-8D63-38239988150B/d/UTM.app/Contents/MacOS/UTM”, , “CFBundleExecutablePathDeviceID”=771751985, , “CFBundleExecutablePathINode”=27694741, […]
LAUNCH: Launched translocated app 0x0-0x7c07c com.utmapp.UTM/<private>, so checking it in with pid 2958.

This installation of UTM was translocated because, exceptionally for an App Store app, it satisfied all three conditions.

Eternal translocation

After its initial translocation, the App Store version continued to be translocated every time it was launched, because it still met all three rules. Because, like most App Store apps, it only grants write permissions to the system, its com.apple.quarantine xattr couldn’t be removed using xattred.

The only way to stop the app from always being translocated was to copy it to a different folder, other than /Applications where it first arrived, deleting the original from /Applications, then running the copy and moving that back into /Applications. While that also enables deletion of the quarantine xattr, that’s not necessary, as running it from a different folder ensures the app doesn’t meet the last of the three rules.

App Store + quarantine = bad news

The combination of an App Store app with a quarantine xattr is a particular problem for users, as those apps are installed direct to their intended final destination, and their permissions discourage the user from trying to move them from there. That combination therefore defaults to satisfying all three requirements for app translocation to occur, which it will every time that app is run.

Without using Terminal’s command tools or third-party utilities like xattred and Mints, there’s no way for the user to discover whether an App Store app has a quarantine xattr, nor to check whether the app is being translocated. As (almost?) all other App Store apps don’t have a quarantine xattr and aren’t translocated, the user is unlikely to suspect those might be occurring, and could account for problems with that App Store app. In this case, purchasing and using the App Store version of UTM puts the app and its user at significant disadvantage compared to obtaining the app direct. I’m sure that Apple doesn’t intend to make App Store versions worse than those obtained outside the App Store.

Summary

App Store apps can be delivered with quarantine xattrs, as a result of which they will undergo translocation.
When delivered with a quarantine xattr, an App Store app will undergo eternal translocation, as even advanced users are unlikely to suspect they might be eligible.
It’s assumed that this example has arisen from error, and isn’t intentional on Apple’s part. The App Store should ensure that the apps it delivers don’t have the quarantine xattr attached, however that might have happened here.
If you suspect any app is being translocated, move it individually to a different folder, run it from there, then move it back again.
Requirements for translocation are sufficiently complicated that even Apple doesn’t understand them, or their consequences.

I’m very grateful to sim, who first brought my attention to this puzzling problem.