Thanks for being a part of WWDC25!

How did we do? We’d love to know your thoughts on this year’s conference. Take the survey here

Is it possible to launch a GUI application that is not killable by the logged in user

I'm trying to develop a GUI app on macOS that takes control of the screen so that user must perform certain actions before regaining control of the desktop. I don't want the user to be able to kill the process (for example via an "assassin" shell script that looks for the process and terminates it with kill).

Based on this post it is not possible to create an unkillable process on macOS.

I'm wondering, however, if it's possible to run the GUI process in root (or with other escalated privileges) such that the logged in user cannot kill it. So it's killable, but you need privileges above what the logged in user has (assuming they are not root). I'm not worried about a root user being able to kill it.

Such an app would run in a managed context. I've played around with Service Background Tasks, but so far haven't found what I'm looking for.

I'm hoping someone (especially from Apple) might be able to tell me if this goal is even achievable with macOS Sequoia (and beyond).

Answered by DTS Engineer in 837601022

You seem to be on a path that DTS can’t follow you down. For example, the “unlock event” you mentioned in most definitely an implementation detail, and hence not supported by DTS.

If macOS 15.* and onward simply do not allow a GUI to be launched by anyone other than the logged in user

That statement doesn’t make sense in the context of macOS’s layered architecture. GUI code is only supported in a GUI login context. Code running in a GUI login context is, by definition, run by that logged in user. If that code switches the user ID to root then it’s still in the same GUI login context, although now it has a mixed execution context.

I referenced TN2083 previously. I strongly recommend that you read it carefully, and specifically the Execution Contexts section. If you do stuff like attempt to open a window from a daemon, you will run into compatibility problems down the line.

I'm wondering if this could be accomplished in conjunction with an Endpoint Security agent.

It’s certainly true that as ES client can prevent signals being delivered to processes.

However, I’m not sure there’s a good way to achieve your high-level goal. Presenting a window ‘above’ all other windows on the system is challenging. At one point I investigated how the screen saver / unlock subsystem works [1] and the answer was that it uses a whole bunch of SPI.

If you decide to ship a product that relies on implementation details rather than API, I encourage you to file one or more enhancement requests for a supported API to achieve your goals.

Share and Enjoy

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

[1] While trying to work out how SFAuthorizationPluginView is able to presents its UI above the screen saver but standard GUI authorisation plug-ins are no longer able to do this.

The above should read "via an assassin shell script" - not sure why Apple replaced it with "*".

First up, the *** stuff. I’ve been working with the forums platform folks to try to get that feature removed, that is, we should either allow a word, or prevent you from posting it, but not allow you to post it and then munge it.

I thought the fix for that had gone in, but it’s possible I missed a memo (well, misunderstood a memo :-). What word was it?

If you add dashes between the letters, you should be able to post it. Once I have the details, I’ll follow up with the forums platform folks.


Regarding your technical question, the situation hasn’t changed since that post you referenced [1]. And I’m gonna repeat my question from that thread: What’s the background to your question?

Share and Enjoy

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

[1] Running GUI programs as root is terrible for security, because our GUI frameworks have a huge attack surface and aren’t expecting to run as root. Also, it puts you in a mixed execution context, where your BSD context is out of whack with your Mach bootstrap namespace and security context, and that causes all sorts of weird problems. See TN2083 Daemons and Agents for more on that.

Thanks for the response. The word I was trying to write was a-s-s-a-s-s-i-n. I.e. a process whose job is to kill another process.

I'm not interested in running a GUI as root per se. What I want to do is have a GUI that takes over the screen (or screens) and prevents access to the user's desktop unless they perform certain authentication steps.

This doesn't need to be a root process, it simply needs to be unkillable by the logged in user. If there were some way to run setuid(X) where X is not the logged in user, that could work.

The word I was trying to write was …

OK. I’m seeing the same behaviour. I’m gonna touch base with the forums platform folks about this.


What I want to do is have a GUI that takes over the screen (or screens) and prevents access to the user's desktop unless they perform certain authentication steps.

OK. And what triggers that situation?

For context, I usually see folks implement this sort of thing in terms of screen unlock, and you can do that using an authorisation plug-in. However, that’s not something you can reliably trigger on demand.

Share and Enjoy

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

OK. And what triggers that situation?

Could be a number of different events. Could be an unlock event (com.apple.screenIsUnlocked).

For context, I usually see folks implement this sort of thing in terms of screen unlock, and you can do that using an authorisation plug-in. However, that’s not something you can reliably trigger on demand.

We are specifically not interested in using an Auth Plugin because we want more flexibility than is offered by the Auth Plugin API (e.g. no biometrics, very prescribed UI).

So the first nut we are trying to crack is this issue of "unkillability" by the logged in user. I'm hoping to get an idea if this is even possible. If macOS 15.* and onward simply do not allow a GUI to be launched by anyone other than the logged in user then I am probably out of luck.

Thanks for your help!

I'm wondering if this could be accomplished in conjunction with an Endpoint Security agent. So my GUI would just run normally as the logged in user, but would be "protected" by an Endpoint Security agent that would trap "kill -9" calls. Could that work?

You seem to be on a path that DTS can’t follow you down. For example, the “unlock event” you mentioned in most definitely an implementation detail, and hence not supported by DTS.

If macOS 15.* and onward simply do not allow a GUI to be launched by anyone other than the logged in user

That statement doesn’t make sense in the context of macOS’s layered architecture. GUI code is only supported in a GUI login context. Code running in a GUI login context is, by definition, run by that logged in user. If that code switches the user ID to root then it’s still in the same GUI login context, although now it has a mixed execution context.

I referenced TN2083 previously. I strongly recommend that you read it carefully, and specifically the Execution Contexts section. If you do stuff like attempt to open a window from a daemon, you will run into compatibility problems down the line.

I'm wondering if this could be accomplished in conjunction with an Endpoint Security agent.

It’s certainly true that as ES client can prevent signals being delivered to processes.

However, I’m not sure there’s a good way to achieve your high-level goal. Presenting a window ‘above’ all other windows on the system is challenging. At one point I investigated how the screen saver / unlock subsystem works [1] and the answer was that it uses a whole bunch of SPI.

If you decide to ship a product that relies on implementation details rather than API, I encourage you to file one or more enhancement requests for a supported API to achieve your goals.

Share and Enjoy

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

[1] While trying to work out how SFAuthorizationPluginView is able to presents its UI above the screen saver but standard GUI authorisation plug-ins are no longer able to do this.

I’m gonna touch base with the forums platform folks about this.

I just received word that this change has rolled out, and I’ve confirmed it for myself. Yay!

Share and Enjoy

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

Is it possible to launch a GUI application that is not killable by the logged in user
 
 
Q