tccd reports Apple Events entitlement check error, despite a process having it

HI! I am developing an application that should utilize ScriptingBridge.framework to interact with another process. Firstly, I created a separate test application for which I have added Apple Events entitlements via "Signing & Capabilities" section in Xcode and updated its Info.plist to have "Privacy - AppleEvents Sending Usage Description". While the test app works fine (I see an automation request popup and the process executes as expected) the main application where I want to integrate this functionality gets closed immediately after reaching the code interacting with Scripting Bridge. On its launch, I see the following error message from tccd in Console:

Prompting policy for hardened runtime; service: kTCCServiceAppleEvents requires entitlement com.apple.security.automation.apple-events but it is missing for accessing={TCCDProcess: identifier=<app bundleID>, ..., binary_path=<path to the app's binary>}

I had no such issues with the test app. Moreover, I should mention that the bundle I want to have with such functionality is stored in another bundle, both main and inner bundles aren't sandboxed, and the target app has Application is agent (UIElement) key set in Info.plist. Can you suggest any ideas as to why processes behave so differently despite having pretty much the same build configurations?

Answered by DTS Engineer in 789671022
Sorry, writing a response during the night in a foreign language was a bad idea...

No worries. I’m horribly jet lagged, so I’m struggling to form coherent sentences myself (-:

However, the message in this popup states that Automation permission is requested by a container app

Yeah, that’s what I suspect. This is working correctly. When a process makes a request, TCC tries to find the responsible code, that is, the nearest ‘parent’ [1] of the process that the user knows about. Because your UI element app is embedded in your container app, the user never sees that app, and thus the responsible code is the container app.

Given that, I think you’re all good. Reply back here if you hit further snags.

Share and Enjoy

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

[1] In quotes because I’m not talking about a parent process here. The algorithm that TCC uses to determine the responsible code is complex and evolves over time. You only have limited input into it, for example, AssociatedBundleIdentifiers is one of its inputs.

I need to get a better understanding of how this is set up in your real product. You wrote:

I should mention that the bundle I want to have with such functionality is stored in another bundle, both main and inner bundles aren't sandboxed, and the target app has Application is agent (UIElement) key set in Info.plist.

Let’s call these your container app and your UI element app. Questions:

  • The UI element app is an app, right? Not something else, like an app extension.

  • Are either of these sandboxed?

  • Where did you app the Apple event capability? On the UI element app?

  • In that TCC error, which bundle ID and path are shown? The container app? Or the UI element app?

Share and Enjoy

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

Sorry, responded in the comment section. Duplicate as a reply:

Ok, considering only the real product:

The UI element app is an app, right? Not something else, like an app extension.

Exactly, that is an app not an app extension or anything else

Are either of these sandboxed?

They aren't sandboxed

Where did you app the Apple event capability? On the UI element app?

Yes, on the UI element app via Xcode "Signing & Capabilities"

In that TCC error, which bundle ID and path are shown? The container app? Or the UI element app?

UI element app

Thanks for the answers.

Let’s rule out the UIElement factor first. If you temporarily remove that key from your UI element app, allowing it to run with a UI, does that help?

Note that you might need to add a dummy main menu nib to allow AppKit to start up with a UI.

Share and Enjoy

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

Tested with your suggestion the issue persists. The error message from tccd persists, the UI element app app gets closed on calling SBApplication(bundleIdentifier:). No crash reports in Console.

Hmmm, I’m not aware of any way that TCC will terminate an app. If there’s no crash report, it’s likely that TCC is triggering an error and something within your app is exiting in response to that error.

Does this happen if you run the UI element app under the debugger? If so, what does it report about the termination?

Share and Enjoy

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

Hi, eskimo! Finally, I was able to check that. This termination mystery was solved: an exit() statement caused app termination. The statement was in the program itself and it had nothing in common with tccd.

However, the issue with tccd that caused the creation of this thread persists. It continues to report the absence of entitlements for Apple Events despite the fact, that the bundle has it.

If we return to our naming convention: "UI element app" is a user agent that has the corresponding plist and gets launched via launchctl command from "container app". UI element app bundle is a part of the container app bundle.

Considering these conditions is it possible that the issue may be with the container app not having the required entitlements?

It sounds like you’re not using SMAppService to set up your launchd agent. Given that, you should list your main app’s bundle ID in AssociatedBundleIdentifiers. Are you doing that already? If not, please try it out?

See the launchd.plist man page for details.

Also, make sure you test on a ‘clean’ machine. I generally test this stuff on a VM, restoring from a snapshot before each test.

Share and Enjoy

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

Probably you are right, I am going to check with your suggestions, thank you! So far I have modified the UI element app so I can run it as a standalone GUI-less app (via Xcode without launchctl invocation or by double-clicking on the bundle). By GUI-less I mean with "Application is agent" key set to YES in Info.plist and without "Main storyboard" key. In this configuration, the app can acquire Automation permissions and interact with Finder via Scripting Bridge.

@DTS Engineer checked with your suggestion to add AssociatedBundleIdentifiers. Whilst tccd now doesn't report this particular error GUI app still doesn't request automation permission (which happens when I run it as a standalone process) on SBApplication call.

OK.

If you add a test button to your container app and then wire it up to some Apple event code that triggers the TCC alert, is your UI element app then able to take advantage of that?

Share and Enjoy

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

@DTS Engineer So, here is what I have investigated. If I put the application bundle inside another bundle I should set entitlements and Info.plist accordingly for both container and nested app. In that case despite the way you are launching a nested application (either via launchctl utility or via Service Management framework). With this setup, I could finally see the message about the process asking for Automation permission. However, the application name in the message wasn't the container's not the nested app's.

OK, seems like you’re making progress.

With regards this…

However, the application name in the message wasn't the container's not the nested app's.

Can you clarify this? It doesn’t parse as a sentence.

Share and Enjoy

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

Sorry, writing a response during the night in a foreign language was a bad idea...

I mean, I have a "container" bundle and a "nested" bundle which I put in "container".app/Contents/MacOS. The container application launches the nested one as an agent.

I tested launching via launchctl and Service Management framework.

It turns out that I have to put "Apple Events" entitlements for both the container and the nested app and update their Info.plists accordingly (put there Privacy - AppleEvents Sending Usage Description), even though only the nested app deals with Scripting Bridge.

When a nested app reaches the execution point where it invokes Scripting Bridge API a corresponding popup from the system appears to get the user verdict (allow/deny access). However, the message in this popup states that Automation permission is requested by a container app that doesn't deal with Apple Events and acts as a simple launcher for the nested one.

It turns out that I didn't need AssociatedBundleIdentifiers in the nested app's Info.plist (so far, I don't know whether it could a problem for notarization).

Accepted Answer
Sorry, writing a response during the night in a foreign language was a bad idea...

No worries. I’m horribly jet lagged, so I’m struggling to form coherent sentences myself (-:

However, the message in this popup states that Automation permission is requested by a container app

Yeah, that’s what I suspect. This is working correctly. When a process makes a request, TCC tries to find the responsible code, that is, the nearest ‘parent’ [1] of the process that the user knows about. Because your UI element app is embedded in your container app, the user never sees that app, and thus the responsible code is the container app.

Given that, I think you’re all good. Reply back here if you hit further snags.

Share and Enjoy

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

[1] In quotes because I’m not talking about a parent process here. The algorithm that TCC uses to determine the responsible code is complex and evolves over time. You only have limited input into it, for example, AssociatedBundleIdentifiers is one of its inputs.

tccd reports Apple Events entitlement check error, despite a process having it
 
 
Q