btm-backgroundtaskmanagementd

backgroundtaskmanagementd is a system daemon introduced with macOS 13 Ventura (released October 2022) as part of a new framework for managing login items and background tasks. Whereas previous macOS versions relied on manually installed Launch Agents/Daemons and login items, Ventura unified these under Background Task Management (BTM) for greater transparency and user control. The backgroundtaskmanagementd daemon maintains a central (proprietary) repository of persistent items and enforces policy, notably requiring user approval or awareness of software that auto-launches at login or runs continuously in the background.

![[btm-open-at-login-bad.png]]Stack Overflow

Initial release (Ventura)

In macOS 13, backgroundtaskmanagementd was responsible for populating the new System Settings > General > Login Items list of “Allow in these Background” apps. It also began issuing system notifications whenever an app installed a Launch Agent/Daemon or login item, alerting the user to newly added background tasks. This was a major security improvement: prior to Ventura, any process could persist itself without user notification. Now, users could see all persistent background components in one place and toggle them off if unwanted. By default, standard users have the ability to disable these items via the UI, unless an organization policy (MDM) prevents it.

Subsequent changes

Apple iterated on BTM in post-Ventura releases. Early Ventura updates fixed some bugs in backgroundtaskmanagementd. For example, macOS 13.1 addressed issues where certain “removal” events were not logged or notifications could fail. A critical security fix in macOS 13.4 patched a logic flaw (CVE-2023-32405) in the Service Management daemon smd that could allow privilege escalation to root (this was related to BTM’s infrastructure, as smd works closely with backgroundtaskmanagementd).

In macOS 14 Sonoma (2023), Apple added a declarative status reporting feature for MDM to query background tasks and tightened sandboxing rules for helper executables. Since macOS 14.2, any background service installed via the new APIs must be sandboxed if the main app is sandboxed (enforcing parity between an App Sandbox app and its launched helper). These changes improved security and manageability, though the core architecture of backgroundtaskmanagementd remained consistent from Ventura onward.

Functions and architecture

backgroundtaskmanagementd manages policy for background task processes and login items. In practice, backgroundtaskmanagementd maintains a database of all registered persistent components on the system, including traditional LaunchDaemons/LaunchAgents, login items installed via the ServiceManagement framework, and background services specified by device management profiles. It coordinates when these background tasks can run (e.g., at login or boot) and gates their execution on user approval status. Some responsibilities include:

Tracking registrations

When a new background launch item is added (either by an app using the new API or by installation of a launchd plist), backgroundtaskmanagementd records it in an internal data store along with metadata (e.g., the item’s identifier, launch path, and whether the user has been notified or has allowed it). It essentially centralizes what was previously scattered (login items, LaunchAgents, etc.) into one managed list.

Policy enforcement

The daemon implements the rules around user approval. By default, new background tasks are allowed to run, but the system will notify the user and list them in settings. If the user explicitly toggles an item off in System Settings, backgroundtaskmanagementd ensures it no longer launches (marking it disabled/disallowed). For enterprise-managed Macs, if an MDM profile pre-approves certain items (via the com.apple.servicemanagement payload), the daemon will auto-approve those and suppress redundant notifications. In all cases, backgroundtaskmanagementd mediates whether a given background task is permitted to start (allowed by policy) or should be blocked.

User notifications and logging

The daemon (in conjunction with a user-space agent) generates alerts like “Background Items Added.” This lets the user know when software has persisted itself for autostart. It also logs these events for security auditing. For example, backgroundtaskmanagementd uses Apple’s Endpoint Security (ES) framework to emit events whenever a new launch item is registered or removed. Security tools or endpoint monitors can subscribe to these ES_EVENT_TYPE_NOTIFY_BTM_LAUNCH_ITEM_ADD events to detect persistence in real time.

BTM Components: Architecturally, backgroundtaskmanagementd works in concert with a few other system components. Each of these will have their own section within the og-apple-security repo eventually (if they are not present already).

Service Management daemon (smd)

smd is the longstanding macOS daemon for the ServiceManagement framework, which responsible for launching helpers, managing privileged helpers via SMJobBless, etc.. In the Ventura era, smd is the bridge between launchd and backgroundtaskmanagementd. It monitors the filesystem for new launchd plist files and responds to ServiceManagement API calls. When it detects a new LaunchAgent/Daemon being installed, it invokes backgroundtaskmanagementd’s routines to register that item before actually launching it. In system logs, you can see this interplay: “smd: Got a fsevent. Doing re-register… Bootstrapping legacy plists” followed by “backgroundtaskmanagementd: registerLaunchItem: … type=legacy daemon, url=…ZoomDaemon.plist”. Here, smd noticed a new launchd plist (Zoom’s daemon) and signaled BTM to register it, then proceeded to bootstrap (load) it via launchd. Thus, smd handles the launchctl interactions, while backgroundtaskmanagementd handles policy and record-keeping.

Private framework

The logic of BTM lives in BackgroundTaskManagement.framework (a private framework). The daemon’s binary resides at /System/Library/PrivateFrameworks/BackgroundTaskManagement.framework/backgroundtaskmanagementd. Both the daemon and the user-agent (below) likely leverage this framework’s classes (e.g. BTMStore, BTMManager) to manipulate the background task database and communicate with each other. Apple’s APIs like SMAppService (in the ServiceManagement framework) under-the-hood talk to this subsystem to register or unregister login items.

BackgroundTaskManagementAgent

In each user login session, a BackgroundTaskManagementAgent runs (as the user) to assist with user-visible aspects. This agent is the one that actually posts notifications to Notification Center on behalf of backgroundtaskmanagementd. Because system daemons running as root cannot directly show UI in a user’s session, the agent serves as backgroundtaskmanagementd’s “UI delegate.” For example, when a new item is added that isn’t suppressed by policy, the agent receives a message to present the “Background Items Added” alert. Unified logs show entries like: “BackgroundTaskManagementAgent: … Posting managed item notification request, triggered by item: … name=someService, type=managed legacy agent, disposition=[enabled, allowed, visible, notified]…”. This indicates the agent posting a notification about a LaunchAgent (someService) that was just registered. The agent also updates the toggle state in System Settings if the user changes it, likely by relaying the user’s choice back to backgroundtaskmanagementd.

Launchd

While not a component of BTM per se, launchd is intimately involved as it is the actual service launcher on macOS. Normally, launchd loads LaunchDaemons at boot and LaunchAgents at login. With BTM in place, launchd still performs the execution, but it works in tandem with smd/BTM. In Ventura, smd uses a LaunchEvents mechanism to watch certain directories (like /Library/LaunchAgents, /Library/LaunchDaemons, and their user equivalents) for changes. Upon detecting a new plist or an update, smd intercepts that event (before launchd auto-starts anything) and calls into backgroundtaskmanagementd to register the item and apply policy. Only then is launchd instructed (via smd) to actually launch the job (if allowed). In system logs this appears as a “Bootstrap by smd” message indicating smd told launchd to load the job. If the item was marked “disabled” by the user, BTM can prevent the bootstrap by pre-emptively adding it to launchd’s disabled list (under the hood, macOS uses /var/db/com.apple.xpc.launchd/disabled*.plist to keep track of disabled jobs per-user). In summary, backgroundtaskmanagementd doesn’t launch processes itself; it coordinates with launchd (via smd) to allow or block launches according to policy.

Reading