Sandboxed SMAppService LaunchDaemon: supported identity and persistent storage?

Technology: Service Management (SMAppService), App Sandbox, launchd, Foundation file URLs.

This is a documentation/support question based on a standalone signed probe. It is not an assertion of a confirmed Apple defect, and it is not a duplicate of the launchd enhancement FB24726121 referenced in DTS thread 844906.

Request Please clarify the supported identity and persistent-storage architecture for this combination of requirements.

We need a sandboxed Mac App Store app to install its bundled, sandboxed SMAppService LaunchDaemon through one in-app action and the required native approval. The LAN listener must be unprivileged and remain available after logout and at boot.

On macOS 27.2 beta 1 (26B5086k), our signed app-like probe launches and accesses its private container as the default root identity. We have read DTS thread 844906’s single-process privilege-drop guidance; this request concerns the additional sandbox, storage, and distribution limits.

Observations • UserName=nobody exits during sandbox initialization with /var/empty home and secinitd UID errors. • An existing non-root account control also traps in libsecinit before main. • SessionCreate=true with that existing non-root account still terminates in libsecinit before main. • Creating a new audit session did not resolve sandbox initialization in this probe. • A retained directory descriptor works with openat after dropping privileges, but ordinary container paths and /dev/fd/directory/child do not. • All diagnostic registrations were removed for these tests; no product data or network listener was involved.

Questions

  1. Is a sandboxed bootstrap that permanently drops groups, GID, and UID before opening a LAN listener a supported architecture for the Mac App Store distribution lane?
  2. How should such a LaunchDaemon obtain an isolated service identity and persistent container with Foundation/MLX-compatible file URLs without an external installer, shared writable storage, manual account/ACL setup, or unsupported sandbox exceptions?
  3. Please identify the supported public-API path, and clearly distinguish Service Management support from App Review guideline 2.4.5 constraints.
  4. If these requirements cannot be combined, please state which ones are mutually exclusive.

Reference: https://developer.apple.com/forums/thread/844906

Expected outcome: documented guidance on a supported arrangement, or a clear statement of which requirements cannot be combined. We are withholding the product’s Release host installation until the identity/storage design is qualified.

We need a sandboxed Mac App Store app to install its bundled, sandboxed SMAppService LaunchDaemon through one in-app action and the required native approval. The LAN listener must be unprivileged and remain available after logout and at boot.

Can't do that in the Mac App Store. LaunchDaemons run as root.

So, before we get to the technical question here, there’s the concern that Etresoft raised. If the goal of sandboxing your daemon is so that you can ship this product on the Mac App Store, it’s not at all clear as to whether that’ll work. While SMAppService is capable of installing a sandboxed daemon from a sandboxed app [1], App Review has traditionally taken a dim view of Mac App Store apps that try to escalate privileges. OTOH, they do allow code to run as root in at least one case, namely Network Extension providers that are packaged as a system extension [2].

I recommend that you talk to App Review to see if they have any guidance here.


Coming back to the technical aspects of this, I don’t think it’s feasible to change user ID in a sandboxed daemon. The App Sandbox was designed for apps, and apps can’t change user ID. There’s precedent for enabling App Sandbox in a daemon [3] but those don’t change user ID.

Critically, the App Sandbox has very strong opinions as to what areas of the file system the process has access to, especially with regards the app container, and I can’t imagine that working if you change your user ID.

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

[1] Starting with macOS 14.2 a sandboxed app can only install a sandboxed daemon; prior to that, sandboxed apps were able to install non-sandboxed daemons.

[2] Internally, NE and ES sysexen work very much like launchd daemons. Notably, NE sysexen are sandboxed and ES sysexen are not, and the former is allowed on the Mac App Store while the latter is not.

[3] Namely, the above-mentioned Network Extension system extensions.

Sandboxed SMAppService LaunchDaemon: supported identity and persistent storage?
 
 
Q