Not getting TCC prompt when launching app

I have an electron app that is signed and notarized. If I zip the app and send it to myself (AirDrop, Dropbox, etc.) it is quarantined (as expected) and it is unable to read files/directories outside of itself.

The app has an external config folder that it must read:

Parent_Folder (Unzipped)
   |- CONFIG
   |- myApp.app

When I launch the app, I don't receive a prompt to allow access to the downloads folder, and as a result, it can't read the CONFIG folder.

However, I can fix it in one of two ways:

  1. Move the .app file (anywhere) and then move it back.
  2. xattr -d com.apple.quarantine myApp.app

After I complete either one of these steps, I can launch the app and then I receive the prompt to allow access. After that, smooth sailing.

What am I missing? I expected that once the user clicks "Open anyway" when presented with the quarantine prompt that it would work.

I have no problems launching the app, but it doesn't have the required permissions until I complete step 1 or 2.

Edit: Even if the permission is already granted (from a previous attempt) it doesn't work until I complete step 1 or 2.

I suspect I’m missing some context here. You wrote:

it is quarantined (as expected) and it is unable to read files/directories outside of itself.

That’s not really how quarantine works. Gatekeeper doesn’t allow a quarantined app to launch and then prevent it from accessing files. Rather, it prevents the quarantined app from launching at all.

I expected that once the user clicks "Open anyway"

There is no “Open anyway” button on modern Gatekeeper alerts, which suggests you’re either working on a very old system or paraphrasing. I suspect it’s the latter. It’d really help if you were precise here, because the devil is in the details.

For examples of the alerts that Gatekeeper can show, see Safely open apps on your Mac (from Apple Support).

Can you post detailed instructions on the steps you’re taking to hit this problem?

Also, I generally test this stuff on a VM so that I know I’m starting from a known ‘clear’ Mac. See Testing a Notarised Product for my specific steps.


Finally, with regards this:

The app has an external config folder that it must read:

Parent_Folder (Unzipped)
   |- CONFIG
   |- myApp.app

This is not a good idea on the Mac. Imagine multiple users share a single machine. The admin then has to choose between:

  • Putting the app in /Applications, which is a problem if different users need different configurations

  • Putting the app in ~/Applications, which wastes a bunch of disk space

If the configuration file never changes, bundle it inside the app.

If the configuration file can change, use FileManager.urls(for:in:) to build a search path and then attempt to locate it in that path.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks for the reply, eskimo!

There is no “Open anyway” button on modern Gatekeeper alerts, which suggests you’re either working on a very old system or paraphrasing. I suspect it’s the latter. It’d really help if you were precise here, because the devil is in the details.

Correct, I was paraphrasing. Sorry about that :)

As I've continued to research this, I've discovered that this is a product of App Translocation/Gatekeeper Path Randomization. So the app is able to talk to resources outside of itself, but it can't find the CONFIG folder because it is running from a randomized path.

To provide a bit of additional context on how the app works:

  • I distribute the signed and notarized app to my client
  • They edit the CONFIG folder (fonts, media, etc.), zip up the parent folder and send it to their client

I don't expect my (non-developer) clients to sign and notarize the app before distribution, so putting it inside the app bundle is not an option.

I'll look into the FileManager solution - it sounds like if I can use that method to determine the URL for the app's untranslocated location that I'll be in business?

[Gatekeeper path randomisation (aka app translocation) means that] it can't find the CONFIG folder because it is running from a randomized path.

Yep. I should’ve put that on my list of reasons why this approach isn’t a good match for the Mac.

To provide a bit of additional context on how the app works:

Thanks for that.

it sounds like if I can use that method to determine the URL for the app's untranslocated location that I'll be in business?

Yeah, that’s not the path I’d recommend. The whole point of app translocation is to prevent you from doing that sort of thing.

A better option would be to provide your clients with a template disk image that includes a symlink to /Applications and instructions on how to copy the app there. That’s a common pattern on macOS and it’s neat because the copied app isn’t subject to app translocation.

You could extend that to include a symlink to /Library/Application Support so your client could add MyAppConfig/* to the disk image and the final client could copy that to /Library/Application Support by dropping MyAppConfig on to that symlink. It’s a two-step process, but it’d put you on a well-trodden path.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks again, Eskimo!

In your proposed solution they would be distributing an unsigned/notarized DMG (unless they registered as developers themselves). It's probably the correct approach nonetheless.

Appreciate your input :)

In your proposed solution they would be distributing an unsigned/notarized DMG

Right. That’ll less than ideal but it’ll work just fine [1].

Having said that, there are other ways to slice this problem. For example, you could distribute a signed and notarised immutable copy of your app that, on launch, tells the user that they need a config file to continue. Your client could then distribute your app and the config file as separate items. Their users are expected to install the app, launch it, and then launch the config file, at which point the app ingests the config file and they’re off to the races.

And this is just one example. You could get even more creative here. It’s just a question of balancing engineer effort, convenience for your clients, and convenience for their users.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] … on modern systems. IIRC 10.14 requires that the disk image itself but signed and notarised to pass Gatekeeper.

Not getting TCC prompt when launching app
 
 
Q