I'm looking for answer or documentation on gatekeeper and launching a MacOS app via a url scheme/custom protocol.
Our application is delivered via a zip file downloaded from the web. We utilize a url scheme. The act of extracting the app from the zip registers the url scheme with the OS.
From previous research/testing we found we had to break the gatekeeper lock (have the user move the app from the downloaded location) to ensure that the url is honored on first launch of the application. To ensure user compliance, we added a check to make sure that the lock has been removed by looking at the quarantine attribute.
This flow is not ideal. I am looking for alternatives and was previously under the impression that if we were to move to a DMG then that would provide the user a better user experience for moving it. However, now that I am getting around to looking into it, I am seeing some implied statements that this is not the case and that the quarantine bit will just be moved from the DMG to the app.
Questions:
- Does a DMG allow the app to be launched via custom protocol without prior launch or movement?
- With a notarized app, will the custom protocol work on a subsequent launch, even without prior movement?
Sorry for the late reply to this, it was outside of the areas Quinn and I normally monitor and we both missed it. In any case, some additional questions were passed over to me through a DTS ticket, so I'm going to answer your questions above and then the other questions that were passed to me.
(Splitting posts for length)
First of all, as a general comment here:
I am looking for alternatives and was previously under the impression that if we were to move to a DMG then that would provide the user a better user experience for moving it.
So, one thing to understand here is that the pattern of using disk images for software distribution is primarily a holdover of what is now "ancient" history, not technical merit. It started when software was being distributed on floppy disk as the easiest way to "exactly" duplicate the contents of the original floppy disk. Originally, these images couldn't even be mounted, so their only purpose was to be written back out to physical media. That pattern was then carried over to CDs and DVDs for largely similar reasons— that is, software was being distributed as a collection of files (one or more apps, documentation, possibly an installer...) and it wasn't clear what the requirements of that particular "source" were*, so the simplest and most reliable way to duplicate "any" given source was to create an image.
*For example, some software would only install from a volume configuration that "looked" like the installer source looked.
If it seems like none of that is all that relevant to modern software distribution... you’re right, it isn't. The system doesn't have any particular "preference" for one mechanism over another and there isn't really any technical reason to prefer one format over the other.
That leads to here:
However, now that I am getting around to looking into it, I am seeing some implied statements that this is not the case and that the quarantine bit will just be moved from the DMG to the app.
In terms of security protections, any security mechanism that we apply to one format MUST also be applied to other formats, otherwise an attacker would simply switch to the other format to avoid that protection.
Now there are differences in the details of how we behave with different formats; however, those differences are generally caused by the specifics of that particular scenario. For example, we generally don't translocate apps that are launched off of read-only media, but that's because the app is inherently protected from modification, so translocation is unnecessary.
Moving to specifics:
Does a DMG allow the app to be launched via custom protocol without prior launch or movement?
With a notarized app, will the custom protocol work on a subsequent launch, even without prior movement?
Yes, both of these generally work for fully notarized apps with or without disk images.
Moving to the other questions I received:
At this point, I am looking at whether I need to be worried about running from a randomized path.
So, the first thing to understand is that a check like this:
To ensure user compliance, we added a check to make sure that the lock has been removed by looking at the quarantine attribute.
...isn't reliable. The quarantine flag is used to store metadata the system uses to make these decisions (which is why stripping it changes behavior), but its existence doesn't guarantee any specific behavior.
Does distributing via DMG automatically handle this? It appears the answer is yes from what I am seeing, even though the quarantine attribute doesn’t fully go away
...but that's simply because it encourages the user to copy the app out of the disk image, and that copy changed the quarantine state. That's exactly the same thing you're doing by asking the user to move their application. If the user is running the app directly out of the DiskImage, then you're in exactly the same situation you were already in without the DiskImage.
As a broader point, I'm not sure the focus on "preflighting" (meaning, trying to validate that your update will someday work) is all that helpful. That's because:
-
It's entirely possible that the user will never need to update your app.
-
It's entirely possible that the system state will change by the time you do need to update, invalidating the entire preflight.
-
It gets in the way of "smart" users. For example, it's possible the reason it's in a read-only location is because it's being shared from a central server, which is also where someone is making sure it's up to date.
-
The preflight heuristic itself is both complicated and error-prone.
The bottom line here is that you're doing all of this work to determine whether or not you should present a somewhat confusing "Please move this app" dialog which may or not be necessary, all to avoid the possibility that you might need to present a fairly simple "please find my app" dialog. Even worse, having done all that preflight work, you might still be unable to update at which point the user is still stuck without a solution.
If you're going to perform some kind of preflight process, then my suggestion would be that you present it as an ignorable notification or alert, then just let the user run the app wherever they like.
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware