Shell script or command notarization

Hi folks


We are working on auth plugins. We wrapped it in .pkg, codesign, notarize everything worked like a charm. Then we added a shell script to clean up all the traces of our plugins. We dropped both .pkg and sh script in dmg, codesigned, etc., everything is fine.


The problem is that now we decided to add a "proper" uninstaller. By proper, we mean something that is going to be launched by double-clicking on it without any additional steps. And thus began our struggle with notarization. So far, I've tried:

1) Simply changed .sh to .command. But didn't find a way to notarize it.

2) I've moved the script in command-line tool, wrap it in AppleScript. Sign executable with Developr ID Application, even notarize it within zip just in case, put it in dmg, notarize and staple dmg. But when I attempt to launch uninstaller, I get "<Uninstaller> can't be opened because the identity of the developer cannot be confirmed."

3) Tried some other weird things like wrapping .command in .app, point to this .command as Executable file in .plist etc.


So the question basically, is there is a proper way to do it? I don't want to create another .pkg to uninstall plugins because .pkg interface is tightly coupled with the installation process and not uninstallation.

Answered by DTS Engineer in 400249022

We've talked about it a bit, and seems like a "proper" way for us is launch it as a command in Terminal.

OK. That presents some challenges. There are three scenarios to cover:

  • User double clicks a script or tool in Finder, it opens in Terminal, and Terminal executes it (A)

  • User runs a script from within Terminal (B)

  • User runs a tool from within Terminal (C)

Case A is interesting because it doesn’t run through Gatekeeper’s standard execution logic. Rather, the Finder passes the script or tool to Terminal as a document and that opens a window (and associated shell) in which to run that document. This triggers Gatekeeper’s document logic. That logic hasn’t been updated to understand notarisation (r. 58097824), and thus Gatekeeper always fails the open document request.

Cases B and C both run through Gatekeeper’s execution logic. Case B has problems because, when you notarise a container, the notary service searches that container for Mach-O images and adds them to the ticket. The script isn’t a Mach-O image, so is not included. This means that Gatekeeper’s execution logic can’t find a ticket for the script, and blocks the execution.

Case C, OTOH, works just fine.

If you want to develop a shell script rather than a tool, there are various techniques that let you package a shell script as a tool, and thus move from B to C.

Another option is to not place this script on to your disk image next to the installer package, but have the installer package install it in an accessible location (like

/Library/Application Support/MyProductName/Uninstall.sh
). Once the script is installed this way it’s no longer quarantined, and thus not subject to Gatekeeper.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

ps DTS is closed 21 Dec through 1 Jan.

By proper, we mean something that is going to be launched by double-clicking on it without any additional steps.

Did you want this to launch as a command in Terminal? Or as an app? This matters because those actions follow very different paths in Gatekeeper.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

ps DTS is closed 21 Dec through 1 Jan.

We've talked about it a bit, and seems like a "proper" way for us is launch it as a command in Terminal.

Accepted Answer

We've talked about it a bit, and seems like a "proper" way for us is launch it as a command in Terminal.

OK. That presents some challenges. There are three scenarios to cover:

  • User double clicks a script or tool in Finder, it opens in Terminal, and Terminal executes it (A)

  • User runs a script from within Terminal (B)

  • User runs a tool from within Terminal (C)

Case A is interesting because it doesn’t run through Gatekeeper’s standard execution logic. Rather, the Finder passes the script or tool to Terminal as a document and that opens a window (and associated shell) in which to run that document. This triggers Gatekeeper’s document logic. That logic hasn’t been updated to understand notarisation (r. 58097824), and thus Gatekeeper always fails the open document request.

Cases B and C both run through Gatekeeper’s execution logic. Case B has problems because, when you notarise a container, the notary service searches that container for Mach-O images and adds them to the ticket. The script isn’t a Mach-O image, so is not included. This means that Gatekeeper’s execution logic can’t find a ticket for the script, and blocks the execution.

Case C, OTOH, works just fine.

If you want to develop a shell script rather than a tool, there are various techniques that let you package a shell script as a tool, and thus move from B to C.

Another option is to not place this script on to your disk image next to the installer package, but have the installer package install it in an accessible location (like

/Library/Application Support/MyProductName/Uninstall.sh
). Once the script is installed this way it’s no longer quarantined, and thus not subject to Gatekeeper.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

ps DTS is closed 21 Dec through 1 Jan.

I think my situation is similar but am not sure I understand possible solutions. I do not have an App proper but a folder to distribute. Essentially, it contains bin and lib folders, with a shell script (with a .command extension) for the user to double-click and run the program in bin. In the bin folder I’ve placed a static build of an ancient FORTRAN program and, because of the deprecation of script languages, Perl5, it too built statically. The perl wrapper does all the pre- and post-execution file manipulations.


I codesign perl, its library modules, and the FORTRAN executable. I codesign the .command file as well. I package the entire folder as a DMG, code sign that, then notarize the signed DMG.


When I download the DMG and open it, double-click the .command icon, it fails to open because Apple cannot check it for malicious software. If I open a Terminal window and “open” the command file the same thing happens.. But if I run it directly like ./commandFile the program runs. I am hoping to spare a Mac user that unfamiliar chore.


You mention there are "various techniques that let you package a shell script as a tool, and thus move from B to C." Would you give an executive summary of those methods?


Thank you.

You mention there are "various techniques that let you package a shell script as a tool, and thus move from B to C."

I’m not sure how that helps in your case; if you double click a tool, it’s blocked by Gatekeeper in the same way as a script. It sounds like you case about case A, in which case there’s no benefit from moving from a shell script to a tool.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks for your time. I suppose one Gatekeepr OK is not bad, compared to what happens when I do not sign items. Also thanks for your tip from another thread to use a pristine macOS virtual machine that is revertible when testing this stuff.

Shell script or command notarization
 
 
Q