Issue with LaunchDaemon running bash showing up as unidentified developer

I have a couple of LaunchDaemon installed helper executables that are calling a bash script. As of MacOS 13, these are now showing up as unidentified developer in Login Items which I am trying to resolve.

I have tried setting AssociateBundleIdentifiers in my plist file but the console tells me it is being ignored because bash does not have a Team Identifier.

I believe the fully correct way to resolve this is to switch to the new Service Management API, but my understanding is that would only work on MacOS 13 and would therefore break my app on older versions of MacOS

My questions are:

  • is there any other way to make my helper as part of my app's login items that I have missed?
  • is there an easy way to make an installer that will work for both newer and older versions of MacOS without having to package two separate versions?

Sample plist file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>AssociatedBundleIdentifiers</key>
	<array>
		<string>com.mycompany.ExampleApp</string>
	</array>
	<key>Label</key>
	<string>com.mycompany.ExampleApp.updater</string>
	<key>ProgramArguments</key>
	<array>
		<string>/bin/bash</string>
		<string>/var/root/Library/Group Containers/com.mycompany.ExampleApp/Library/Application Support/update.sh</string>
	</array>
	<key>StandardOutPath</key>
	<string>/var/root/Library/Group Containers/com.mycompany.ExampleApp/Library/update.log</string>
	<key>WorkingDirectory</key>
	<string>/var/root/Library/Group Containers/com.mycompany.ExampleApp/Library/Application Support/</string>
	<key>WatchPaths</key>
	<array>
		<string>/var/root/Library/Group Containers/com.mycompany.ExampleApp/Library/Application Support/latest.app.zip</string>
	</array>
</dict>
</plist>

This facility relies on the concept of responsible code, and the system has a very hard time tracking that when you use a script. I discuss this more, in a different context, in On File System Permissions.

My general advice on this front is to switch to using a Mach-O executable. You can then either put the actual functionality in that executable, or use it to run your scripting executable of choice. Your executable should get AssociatedBundleIdentifiers working. And if the scripting executable does something that triggers TCC then that should work too, because the system will be able to track responsibility from the scripting executable child process to your executable.

I believe the fully correct way to resolve this is to switch to the new Service Management API

I’m not 100% sure that’ll actually help, but it certainly worth giving it a try. SMAppService is pretty easy to adopt.

my understanding is that would only work on macOS 13

Correct.

and would therefore break my app on older versions of macOS

Installing a daemon with SMAppService results in a launchd daemon just like any other launchd daemon (well, apart from the responsible code tracking :-). So, you can just use SMAppService if it’s present and then fall back to your existing installation mechanism if it’s not.

Share and Enjoy

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

Issue with LaunchDaemon running bash showing up as unidentified developer
 
 
Q