MacOS Tools/Alerts/Terminals as root?

I’ve got a ticket or three open with SH, but as far as I can tell simplegateway is spawned by a LaunchAgent on macOS. This is an understandable as it’s a requirement for the Remote Desktop functionality to work.

As a primer for those that don’t know, SH’s Remote Access LaunchAgent spawns the simplegateway as root when a macOS box is at the Loginwindow. When running at the loginwindow, SH tools/alerts/terminals run as root. Once a user logs into the box, the LaunchAgent re-spawns simplegateway as the user. This allows for remote access, but tools/alerts/terminals run as the user.

Why this matters is most macOS boxes that aren’t in labs are virtually never logged out. True for desktops and even more so for laptops, so no privileged automation can occur.

What I’m trying to work out is if I’m missing some mechanism that SH has in place to run privileged/root tools/alerts/terminals while a user is logged in. I’d expect one of two solutions. I can’t see any signs of either on my 5.1.8 trial.

  1. A privileged helper tool would be the most “correct” way to handle this, It’s a non-trivial bit of coding, but would provide a secure privileged helper that simplegateway could call to run tools/alerts as root. Terminals could be spun up with the privileged helper, but I think it would require spawning another simplegateway.

  2. A LaunchDaemon that spawns a simplegateway running as root. The SH server would need to manage the sessions and send/process tools/alarms/terminals to the LaunchDaemon spawned simplegateway.

I disabled the LaunchAgent and created a LaunchDaemon for simplegateway. Of course Remote Desktop does not work and isn’t even offered. Tools/Alarms functioned and executed as root. However , no sessions function, no terminal, diagnostics, or tunnels. Surprised/not surprised. I can understand the need for running as the user for remote control, but I’m surprised for the need on file sharing and tunnels. Terminals seem like a visual representation of the terminal, so maybe that’s the issue there.

If you read to here you’re a bit of a masochist or running into the same issue as me. Fingers crossed that I’m just missing something obvious.

I put this request in a while back (before the community here). I still have yet to hear anything.

It’s SUPER annoying - and yes, I’ve done the launch daemon creation, but it doesn’t help in a RDC scenario. I haven’t had the time yet to try it, but I might be able to craft something that will work - which is, again, annoying since we pay for this.

While I understand your frustration and share your pain, and I wish I hadn’t spent the hours on this that I have it’s not a simple feature to code. To do it right, it means fundamentally changing the way SimpleHelp works on macOS vs Linux and Windows.

TLDR: Fixing this requires fundamentally changing the way the app works on macOS vs Linux/Win. There is a workaround. Fire a script/app that backgrounds the same process as the LaunchAgent and only let it run in the context of the loginwindow. Make sure to check for existing processes or you’ll spawn more SimpleGatway process on every logout.

The way SH works now: A single SimpleGateway runs as a service. On windows, it runs as SYSTEM, on Linux as root, on Mac as a LaunchAgent (root at the loginwindow, as the user in session). That single service acts as the broker for and spawns all other instances of the app for all sessions.

On macOS anything with access to the GUI has to run as a LaunchAgent, full stop. Even cron is a LaunchDaemon, so an app started there won’t have access to the GUI.

So in order to fix this issue, SimpleHelp will have to completely change the way their software loads on macOS and the way their client interacts with the server. They’ll need to add a LaunchDaemon and an LaunchAgent for the simplegateway. Both will need to communicate with the SH server and the SH server will have to broker which service is handled by which launchd instance. Bits that require GUI Access will have to be handled in sessions started by the LaunchAgent instance of SimpleGateway and bits that need privileged access will have handled in sessions/by the LaunchDaemon instance of SimpleGateway.

This brokering of services to different instances dependent on how they were launced isn’t the way SH is working for the other two supported platforms, so I get why it’s been a slow delivery. In a support response to me @gchristelis did say this (in some form or another) is scheduled for 5.3.

All that said there’s a less than ideal, but fully functional workaround. Write a script that spawns the same process as the current LaunchAgent, but background the process with “/path/to/osxwrapper &”. Call that script in a LaunchAgent that runs only in the “loginwindow” context and make sure to keep the “AbandonProcessGroup” as true. Simple help will run as root and crazy enough it works. Make sure your script has checking for existing SimpleGateway processes, or else it will spawn instances every time you log out.


  1. I don’t think this is an OS approved way of handling a LaunchAgent. There’s no way SH should do this as a quality developer, but it is currently a workaround that functions.
  2. Whatever spawns the SimpleGateway is what owns it and what requires TCC access. So if you spawn it with a zsh script, zsh needs permission to record your screen and Accabilty Access. Decidedly not ideal.
  3. I’m writing an app that I can sign and notarize to be called to spawn the process. That way the app can be given the permissions for TCC instead of the shell. I’ll probably have the app work out download and installation too just for simplicity sake.

I’ve already spent a too much time on this, and I’m still trialing the product! So it’ll be a bit before I get it on GitHub but overall I think SH is doing some fantastic work at a very decent price point.



I was working on the pseudo login function that Apple released in Mojave and now is full blown in Catalina. Using this, I can have my scripts run as the logged in user, sudo into the other user using JIT login process and then run the script as said user - and then finally killing the session as the logged in user.

A lot to work around with as well as assuming that everyone has a local admin pre-set on the box (which we do and it’s 100% the same across the board using a cloud authentication) so it might work out.

If you get through with your app and need someone to break it - I’d be more than happy :slight_smile:

I’ll post the GitHub project here when I’m closer to done. For sure I’d look at ‘tricking’ the SimpleGateway into staying running after being called as root by a loginwindow -only LaunchAgent.


A related challenge is how we migrate existing services to a LaunchDaemon and LaunchAgent approach. Realistically, we’ll need to support the legacy method to give services the chance to continue to operate until they find themselves in the loginwindow context (and therefore running as root), where they can then potentially install and configure the daemon.

I tried to write a reply here a couple times, but I think that the complexity of that situation Really comes down to how you handled mackintosh upgrades at the moment. How do they happen now? By what mechanism are they scheduled and by what mechanism are they carried out?

It seems like the only thing that you would have to continue to support The old launchagent simplegateway Running like the new launchagent simplegateway, but Send whatever signal is needed for aschedule an upgrade and have it fire the first time SimpleGateway is running as root.

Not knowing the existing upgrade mechanism makes it hard to speak to but it doesn’t seem like it’a too much of a hassle. I’m sure I’m missing something, but luckily I’m not stuck with working it out :smiley:.

Any updates on this? I am dying to be able to run scripts as another user in a tool.

It was a bit of a nightmare to put together and it’s totally offered as-is, but here you go …

You will need to edit the preinstall script and use munkipkg to create an installer that will work with your simplehelp deployment. As an FYI, you will not have full control of the computer until after a logout our restart. The installer builds and fires a LaunchDaemon to ensure the launcher app is deployed correctly. After a restart/logout, the aforementioned LaunchAgent takes over.

As an aside, the app is signed and notarized.