Is it possible for a launch daemon to inherit TCC permissions from its enclosing app bundle?

I'm developing an Accessibility-enabled app that includes a helper app registered as a launch daemon using SMAppService. This daemon will connect to HID which requires both being root as well as having Accessibility (or Input Monitoring) permissions. I want this app to have as little friction for the user as I can manage.

One friction I'd like to avoid is requiring the user to grant more than one application permission to use Accessibility features. So I'm wondering if I can set up the launch daemon so that it inherits the TCC permissions of its parent bundle.

I'll note that the one way I've found that works is to not have the helper app have its own app bundle, but rather just have it be an executable placed alongside the main executable in enclosing bundle's Contents/MacOS directory. This has the disadvantage though of having the helper process and main process have the same name in Activity Monitor, which I think will be confusing to users.

So in short, is there a supported way for a bundled application with its own CFBundleName / CFBundleDisplayName key to run as a launch daemon and also inherit Accessibility permissions from its parent app bundle?

Answered by DTS Engineer in 912659022

In general it’s not possible for a daemon to inherit its container app’s TCC privileges because of the potential for a difference in scope. Some TCC privileges are per user, so the fact that one user granted the privilege to the container app should not grant the privilege to a daemon, which is by definition system-wide.

Now, IIRC Accessibility is a system-wide privilege, and thus this could be made to work. However, it sounds like it doesn’t, which isn’t surprising. My experience is that TCC’s ability to trace from a daemon to its container app is rather limited, even if the daemon is installed via SMAppService, meaning that the OS in general knows where it came from.

Written by guygizmo in 853725021

the one way I've found that works is to not have the helper app have its own app bundle, but rather just have it be an executable placed alongside the main executable in enclosing bundle's Contents/MacOS directory.

Interesting. I’m surprised that works.

Regardless, I think you have a trade-off to make here:

  • You can use this technique, which makes it easier for the user to grant the Accessibility privilege but could cause confusion in Activity Monitor and so on.
  • You can put your daemon in an app-like wrapper, which will give you the result you want in Activity Monitor but makes it harder for the user to enable Accessibility.

Regardless of what you choose, I think it makes sense for you to file a bug requesting that we add better support for this.

Please post your bug number, just for the record.

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

In general it’s not possible for a daemon to inherit its container app’s TCC privileges because of the potential for a difference in scope. Some TCC privileges are per user, so the fact that one user granted the privilege to the container app should not grant the privilege to a daemon, which is by definition system-wide.

Now, IIRC Accessibility is a system-wide privilege, and thus this could be made to work. However, it sounds like it doesn’t, which isn’t surprising. My experience is that TCC’s ability to trace from a daemon to its container app is rather limited, even if the daemon is installed via SMAppService, meaning that the OS in general knows where it came from.

Written by guygizmo in 853725021

the one way I've found that works is to not have the helper app have its own app bundle, but rather just have it be an executable placed alongside the main executable in enclosing bundle's Contents/MacOS directory.

Interesting. I’m surprised that works.

Regardless, I think you have a trade-off to make here:

  • You can use this technique, which makes it easier for the user to grant the Accessibility privilege but could cause confusion in Activity Monitor and so on.
  • You can put your daemon in an app-like wrapper, which will give you the result you want in Activity Monitor but makes it harder for the user to enable Accessibility.

Regardless of what you choose, I think it makes sense for you to file a bug requesting that we add better support for this.

Please post your bug number, just for the record.

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

Interesting. I’m surprised that works.

This has me wondering now, is this is supported behavior? I'm hesitant to rely on something that could be removed in a future release. I suppose it does make some sense, since Accessibility permissions are granted to an app bundle and it'd be impossible for a bundled standalone executable to have the permission if this wasn't the case. And it has been working for at least five years now.

Regardless of what you choose, I think it makes sense for you to file a bug requesting that we add better support for this.

To be perfectly frank, the process of granting permissions in macOS is a mess, so I feel like my bug report would be a lot more comprehensive than that. My app requires as many as four permissions from the user (system extension, background items, accessibility, screen recording) and could be more depending on how things play out with granting the launch daemon permissions. Each permission has a different flow, and it required spending a lot of time creating a bespoke UI for walking users through it complete with screen shots highlightling what to click, because the process is not that straight-forward for novice users. And it's going to be a nightmare to localize.

macOS desparately needs a standard dialog that allows an app to grant all of its needed permissions to itself and any helper apps, similar to what you see when installing an extension in a browser like Chrome. Something that lets the user see exactly what they're agreeing to, but lets them grant it with a simple "yes" or "no" rather than a cumbersome series of steps.

Accepted Answer
Written by guygizmo in 912728022

I'm hesitant to rely on something that could be removed in a future release.

Unfortunately I don’t think there’s a way around that when it comes to TCC. Regardless of this specific issue, there is basically no documentation for the TCC edge cases that crop up on macOS (multiple instances of an app, user vs system-wide privileges, launchd daemons and agents, and so on). I encourage you to file a bug requesting such documentation, but in its absence you kinda have to make a judgement call as to what’s likely to keep working and the consequences of it changing.

Note If you do file a docs bug here, please post your bug number, just for the record.

Written by guygizmo in 912728022

To be perfectly frank, the process of granting permissions in macOS is a mess

I understand where you’re coming from )-: But fixing that is a big effort, versus the small effort required to fix the specific case you care about.

Written by guygizmo in 912728022

macOS desparately needs a standard dialog that allows an app to grant all of its needed permissions

Curiously, we recently introduced something like that, but only for managed devices. Check out WWDC 2026 Session 206 What’s new in managing Apple devices, starting around 10:56.

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

This has me wondering now, is this is supported behavior?

What is "this"? I think you two might have different concepts of what "works" means in this case.

You can absolutely put a launch daemon executable alongside the main app. That's the default and expected configuration. Making it into an app-like bundle is more complicated. The process seems easy enough but it sure took me a long time and many attempts to get it right.

But that just gives you standard launch daemon behaviour. You may not be getting the TCC and Accessibility behaviours that you're asking about.

This has the disadvantage though of having the helper process and main process have the same name in Activity Monitor, which I think will be confusing to users.
So in short, is there a supported way for a bundled application with its own CFBundleName / CFBundleDisplayName key to run as a launch daemon and also inherit Accessibility permissions from its parent app bundle?

Or is this, and only this, what you're asking about?

If you're happy with the current TCC and Accessibility behaviour, then I recommend you just ignore Activity Monitor. If users vandalize your processes, tell them not to do that or else it won't work. There are tons of duplicate process names in Activity Monitor. Why would they care about yours?

the process of granting permissions in macOS is a mess, so I feel like my bug report would be a lot more comprehensive than that

Again, I think you're talking about different things. That flow and all those barrers aren't bugs. They are by design. They are "the feature". And they're very fragile and often change. They should be tested in any beta or new OS release, no matter how minor. Code defensively.

My recommendation is to focus on your core app features and treat any of those extras that require user assent as "nice to have". Accessibility looks great from a marketing perspective, but you shouldn't depend on it. I have one app that does some of that and it's really annoying. I would greatly prefer if the app were just stand alone didn't nag me with all those accessibility and integration settings. They're broken half the time anyway. And this is a really high-quality app otherwise. These things are almost anti-features.

Unfortunately I don’t think there’s a way around that when it comes to TCC. Regardless of this specific issue, there is basically no documentation for the TCC edge cases that crop up on macOS (multiple instances of an app, user vs system-wide privileges, launchd daemons and agents, and so on).

Good point. I think the fact that this behavior has been working for many years suggests that it's likely to continue for a while longer. And as I mentioned, it'd be a problem if only the main executable of an application bundle could be granted TCC permissions, and not the standalone executables that live next to it.

Curiously, we recently introduced something like that, but only for managed devices. Check out WWDC 2026 Session 206 What’s new in managing Apple devices, starting around 10:56.

That's encouraging and certainly an improvement. I hope Apple brings this sort of flow to every day users on non-managed devices!

What is "this"? I think you two might have different concepts of what "works" means in this case.

I did broaden what I was discussing, but the "this" was about having a secondary standalone executable in the app bundle being granted Accessibility permissions along with the main executable.

Or is this, and only this, what you're asking about?

The bit about Activity Monitor is the disadvantage of the approach I was referring to.

If you're happy with the current TCC and Accessibility behaviour, then I recommend you just ignore Activity Monitor. If users vandalize your processes, tell them not to do that or else it won't work. There are tons of duplicate process names in Activity Monitor. Why would they care about yours?

This is what I intend to do. And of course Activity Monitor is full of duplicate or inscrutible process names. But all else being equal I like software that makes things as clear as possible. Having the secondary process being named something like "MyApp System Service" or similar would make it a lot clearer, and being that I'm the sort of power user who appreciates that sort of thing, there are likely others out there too. And a significant portion of the userbase of the app I'm developing is power users.

Again, I think you're talking about different things. That flow and all those barrers aren't bugs. They are by design. They are "the feature". And they're very fragile and often change.

Yes, they are by design, but what you are describing is something that is badly designed and implemented, which is why I am critical of it. I know all too well how fragile, buggy and subject to change the process of granting these permissions is, because I've been working with them extensively ever since they were introduced in OS X 10.9.

My recommendation is to focus on your core app features and treat any of those extras that require user assent as "nice to have". Accessibility looks great from a marketing perspective, but you shouldn't depend on it.

I'm afraid this isn't a useful suggestion. For a whole class of apps, Accessibility permissions aren't a "nice to have", they are a hard requirement, and this is the case of the app I'm working on. In fact all four of the permissions I mentioned earlier are all required in order for the app to run, which is why I had to make a bespoke bit of UI that walks the user through granting all of them before the app will even launch.