SMAppService LaunchDaemon: is privilege drop followed by same-PID exec supported before Mach service check-in?

I’m designing a least-privilege system LaunchDaemon registered with SMAppService, and I’d like to clarify whether the following architecture is supported by public macOS contracts.

The LaunchDaemon declares a MachServices entry. Its steady-state service must run as a dedicated non-root account and later creates an NSXPCListener for that Mach service.

We currently launch the daemon directly using UserName, GroupName, and InitGroups=false.

However, InitGroups=false does not appear to guarantee that the resulting process supplementary-group list is limited to the service’s intended group. In testing, the daemon received a supplementary group outside our accepted set.

We therefore do not want to depend on incidental inherited launch-time group state.

We are considering this alternative:

  1. launchd starts a small, fixed, code-signed bootstrap executable as root.

  2. The bootstrap reads the target UID/GID from an existing protected root-owned binding record.

  3. It establishes an exact credential state using public BSD APIs, conceptually:

    setgroups(...) setgid(...) setuid(...)

  4. It verifies the resulting non-root credentials.

  5. It creates no XPC listener or storage connection while privileged.

  6. Without forking, it permanently replaces itself using execve() (or possibly POSIX_SPAWN_SETEXEC) with another fixed, separately signed executable in the same bundle.

  7. That non-root executable independently validates its security state and then creates NSXPCListener(machServiceName:) for the Mach service declared by the original LaunchDaemon job.

The bootstrap would not remain as a privileged parent or supervisor.

My main questions are:

  1. Is a same-PID exec after permanent UID/GID/supplementary-group reduction supported for an SMAppService system LaunchDaemon before it checks in to its declared Mach service?

  2. Does the exec-replaced process retain the launchd/bootstrap context required for NSXPCListener(machServiceName:) to check in to that Mach service?

  3. If so, what execution context must be preserved across exec (for example bootstrap context, environment, file descriptors, or Mach rights)?

  4. Is there a documented way to preserve only the context required for the LaunchDaemon/Mach-service relationship without carrying unintended root-derived capabilities into the non-root executable?

  5. Would SMAppService.unregister() / normal launchd termination continue to treat the exec-replaced process as the same LaunchDaemon job?

If this topology is not supported, is there an Apple-supported way to establish an exact supplementary-group set before a non-root SMAppService LaunchDaemon begins handling its Mach service?

The goal is to avoid relying on undocumented launchd behavior, incidental supplementary groups, private APIs, or a long-lived privileged helper.

I’m specifically looking for the supported contract here rather than whether this happens to work on a particular macOS release.

SMAppService LaunchDaemon: is privilege drop followed by same-PID exec supported before Mach service check-in?
 
 
Q