<!-- llms-explorer concept facts · https://llms-explorer.com/tree/smappservice-login-items-and-privileged-helpers-for-mac-app-store-versus-developer-id/ · pack 2026-10-02 · ~1056 tokens -->

# SMAppService login items and privileged helpers for Mac App Store versus Developer ID

> Source-anchored research for SMAppService login items and privileged helpers for Mac App Store versus Developer ID. Run status: COMPLETED.

Parent: [macOS App Sandbox Networking and Entitlements](https://llms-explorer.com/tree/macos-app-sandbox-networking/) · 4 facets · 10 facts · page: https://llms-explorer.com/tree/smappservice-login-items-and-privileged-helpers-for-mac-app-store-versus-developer-id/

## How it works

- SMAppService requires that when a sandboxed app registers a daemon, that daemon is itself sandboxed. Apple DTS called this a deliberate change, enforced in macOS 14.4 and not listed in the release notes. An earlier restriction appeared in macOS 14.2. (medium confidence) (verified as of 2024-03-01) — [source](https://developer.apple.com/forums/thread/748124)

## Problems, failure modes and limitations

- A Mac App Store app cannot bundle an unsandboxed privileged helper: Apple DTS states all code shipped via the MAS must be sandboxed, and SMJobBless was never usable from a sandboxed app. DTS advises shipping the privileged daemon as a separate product (installer package or separate app that uses SMAppService), downloaded outside the MAS. (high confidence) — [source](https://developer.apple.com/forums/thread/763977)
- SMAppService.agent installs a per-user LaunchAgent only (current user, ~/Library/LaunchAgents); the API cannot install an agent for all users (Apple DTS). (medium confidence) — [source](https://developer.apple.com/forums/thread/745720)
- A helper-app login item (SMAppService.loginItem(identifier:)) must be bundled at MyApp.app/Contents/Library/LoginItems/Helper.app. The older SMLoginItemSetEnabled is deprecated from macOS 13. Status 78 (EX_CONFIG) means launchd rejected the job plist; a stale Launch Services database from many dev builds is a common cause. (medium confidence) — [source](https://developer.apple.com/forums/thread/726826)

## Comparisons and alternatives

- SMAppService.Status has four values: notRegistered, enabled, requiresApproval, notFound. A user can disable the item in System Settings > Login Items, which leaves it disallowed in the background-task database. The app should read status and prompt rather than assume success. (medium confidence) — [source](https://theevilbit.github.io/posts/smappservice/)

## Facts and statements

- Under the same restriction, sandboxed daemons on macOS 14.4 may not set StandardInputPath, StandardOutputPath or StandardErrorPath in their launchd plist; registration fails if they do. (low confidence) (verified as of 2024-03-01) — [source](https://developer.apple.com/forums/thread/748124)
- App Review Guideline 2.4.5 forbids MAS apps from requesting escalation to root or using setuid (v), from auto-launching or running code at startup or login without consent (iii), and from downloading or installing additional code or standalone apps (iv). Login items need an explicit user opt-in; root helpers are rejected. (medium confidence) (verified as of 2026-10-02) — [source](https://developer.apple.com/app-store/review/guidelines/)
- SMAppService daemons and agents live inside the app bundle: the daemon plist at Contents/Library/LaunchDaemons/<id>.plist, with the executable referenced by a bundle-relative path. Registering a daemon requires user approval in System Settings, then admin authentication. After approval, re-registering needs no further authentication. (medium confidence) — [source](https://theevilbit.github.io/posts/smappservice/)
- SMAppService.mainApp (macOS 13+) registers the app itself as a login item with no helper bundle. Secondary sources describe it as sandbox and App Store compatible. Not checked against Apple's reference page. (low confidence) — [source](https://theevilbit.github.io/posts/smappservice/)
- Developer ID twin build: a non-sandboxed build can bundle a privileged daemon, register it with SMAppService.daemon (macOS 13+), and run it as root after user approval. The MAS build should omit this and use only mainApp or loginItem. The two builds need separate entitlements and targets. (medium confidence) — [source](https://theevilbit.github.io/posts/smappservice/)
