Skip to content

PersistenceExecution

Login Items and BTM Database on macOS

Login Items and the Ventura+ Background Task Management store list login items, agents and daemons, with developer, team ID and approval state.

Location
/private/var/db/com.apple.backgroundtaskmanagement/BackgroundItems-v*.btm
Proves
Which login items, agents and daemons were registered, by which developer, and whether they were allowed
Timestamps
NSKeyedArchiver dates (Mac absolute time, UTC) plus file system times
Access
root and Full Disk Access (BTM store); owning user (legacy backgrounditems.btm)
Retention
Until the item is removed or sfltool resetbtm rebuilds the store
Collection
Aftermath, sfltool dumpbtm, ditto

What it is

Login Items are apps and helpers that start when a user logs in. Their storage has changed twice, giving three formats. Up to macOS 10.12 they lived in a preferences plist; from 10.13 High Sierra a per-user backgrounditems.btm file held them as bookmark data. macOS 13 Ventura introduced Background Task Management (BTM): a single system store, managed by backgroundtaskmanagementd, that tracks login items, launch agents and launch daemons together, drives the Login Items pane in System Settings, and notifies the user when a new background item is added.

For investigators, BTM is valuable because it attributes each item to a developer and team ID and can keep a record after the plist or app that created it is gone.

Where it lives

macOSPathFormatProtection
up to 10.12~/Library/Preferences/com.apple.loginitems.plistplistUser
10.13-12~/Library/Application Support/com.apple.backgroundtaskmanagementagent/backgrounditems.btmBinary plist, NSKeyedArchiver with bookmark blobsUser
13 Ventura+/private/var/db/com.apple.backgroundtaskmanagement/BackgroundItems-v<N>.btmBinary plist, NSKeyedArchiverroot + Full Disk Access
All/private/var/db/com.apple.xpc.launchd/loginitems.<UID>.plistplistService Management login items (SMLoginItemSetEnabled)

The <N> changes with releases (v4 was the name used when Ventura shipped, v7 was seen on 13.2, and v16 is reported on recent releases), and older-version files can remain beside the current one. Collect every .btm file in the folder. BTM holds items for all users, keyed by user.

What it proves

  • A login item, legacy agent/daemon or app-bundled SMAppService job was registered, and for which user.
  • The developer name and team identifier from the code signature, the bundle identifier and the parent app.
  • The executable path and the URL of the plist or bundle.
  • Whether the item was enabled, allowed by the user, hidden and whether the user was notified.
  • Items installed by MDM under a Service Management payload.

It does not prove that the item executed. A record may also refer to a plist or bundle that no longer exists.

Key fields

sfltool dumpbtm and DumpBTM print per item:

FieldMeaning
UUIDRecord identifier
NameDisplay name
Developer Name / Team IdentifierFrom the code signature
TypeBit field: 0x2 app, 0x4 login item, 0x8 agent, 0x10 daemon, 0x20 developer, 0x10000 legacy, 0x80000 curated
DispositionBit field: 0x1 enabled, 0x2 allowed, 0x4 hidden, 0x8 notified; e.g. [enabled, allowed, visible, notified] (11)
IdentifierItem identifier, often the label or bundle ID
URLPlist or bundle location
Executable PathProgram that runs
GenerationRecord generation counter
Assoc. Bundle IDsFrom AssociatedBundleIdentifiers in the plist
Parent IdentifierContaining app

In the raw store (as exposed by bgiparser) item keys include uuid, teamIdentifier, disposition, generation, modificationDate, associatedBundleIdentifiers, url, bundleIdentifier, type, identifier, executablePath, container, developerName and executableModificationDate.

Timestamps

modificationDate and executableModificationDate are NSDate values inside the keyed archive, which store Mac absolute time (seconds since 2001-01-01 UTC); parsers convert them. The .btm file's own APFS times show the last store update. For legacy backgrounditems.btm there are no per-item dates: rely on file times, FSEvents and logs.

Retention

Records remain until the user or developer removes the item, the app unregisters it, or sfltool resetbtm rebuilds the store. Log entries follow normal unified log retention.

Collection

# Live, root, Terminal with Full Disk Access
sudo sfltool dumpbtm > ./case/btm_dump.txt
sudo ditto /private/var/db/com.apple.backgroundtaskmanagement ./case/btm
for u in /Users/*; do
  f="$u/Library/Application Support/com.apple.backgroundtaskmanagementagent/backgrounditems.btm"
  [ -f "$f" ] && sudo cp -p "$f" "./case/bgi_$(basename "$u").btm"
done
# BTM activity
log show --info --predicate 'subsystem == "com.apple.backgroundtaskmanagement"' --last 7d
  • Aftermath collects login items among persistence mechanisms.
  • UAC collects loginitems.*.plist from /private/var/db/com.apple.xpc.launchd; add the BTM folder manually if your profile does not include it.
  • Never run sfltool resetbtm on evidence: it rebuilds the database.

Parsing

  • sfltool dumpbtm (built into macOS) on the live system.
  • DumpBTM (objective-see/DumpBTM): open-source equivalent that can also parse a copied .btm file programmatically (build with Xcode).
  • bgiparser (mnrkbys/bgiparser): parses both legacy backgrounditems.btm and BackgroundItems-v*.btm to JSON: python3 bgiparser.py -f ./case/btm/BackgroundItems-v16.btm -o btm.json.
  • Plaso macos_background_items_plist and macos_login_items_plist plugins; the documented pattern covers BackgroundItems-v[3-9].btm, so rename or test newer versions.

Investigator tips

  • Compare each BTM URL with the file system: an entry whose plist or app no longer exists is a strong lead for cleaned-up persistence.
  • A missing or unexpected Team Identifier for an item that imitates a known vendor is worth a close look.
  • Items with the hidden bit or "not notified" disposition were never surfaced to the user.
  • Endpoint Security emits ES_EVENT_TYPE_NOTIFY_BTM_LAUNCH_ITEM_ADD and ..._REMOVE on macOS 13+, so EDR telemetry may preserve registrations the store no longer shows.
  • TCC grants often follow a new background item; check TCC.db for the same bundle ID or path.
  • Pivot from each item to its plist in LaunchAgents/LaunchDaemons and to Gatekeeper evidence for its binary.

See also