Skip to main content
The Ops Playbook

Stopping App Update Tickets: Automating Background Task Approval

Stop manual login-item approvals for Chrome, Zoom and Slack updaters by pre-authorising Background Task Management via MDM and Jamf smart groups.

Stopping App Update Tickets: Automating Background Task Approval
Isla MorganIsla Morgan9 min readTier L235 min

This playbook covers

Share

Every helpdesk running a fleet of Macs knows this ticket: “Chrome/Zoom/Slack keeps telling me to update but nothing happens.” The user clicks “Update”, the app relaunches, and it is still the old version. Nine times out of ten the actual root cause has nothing to do with the app itself — the updater’s background helper was silently blocked by macOS Background Task Management the first time it tried to register a LaunchAgent, and no one ever approved it in System Settings.

#The Old Way vs the New Way

The old way is a technician remoting in, opening System Settings > General > Login Items & Extensions, scrolling through a list of cryptic bundle identifiers, and manually flipping a toggle for the user. Multiply that by every laptop that gets re-imaged, every new hire, and every app vendor who ships a new updater helper with a slightly different label, and you have a permanent, low-value ticket queue that never actually gets smaller.

The new way removes the human from the approval loop entirely. We pre-authorise the specific updater helpers we trust at the MDM layer using the com.apple.servicemanagement payload, we detect version drift with a Jamf Pro Extension Attribute instead of waiting for a user complaint, and we let a Smart Group trigger a silent re-install policy the moment drift is detected. The technician’s job shifts from “approve this popup” to “watch a dashboard for outliers.”

macOS Background Task Management automation

#Prerequisites and Permissions

  • macOS 13 Ventura or later on target devices (Background Task Management was introduced in Ventura and is the only supported control point for this behaviour).
  • Devices supervised via Automated Device Enrolment through Apple Business Manager. Unsupervised devices will still show the user a one-time confirmation dialog even with the payload installed.
  • Jamf Pro role with permissions: Create/Edit Configuration Profiles, Create/Edit Extension Attributes, Create/Edit Smart Computer Groups, Create/Edit Policies. In Intune the equivalent is Configuration Profile Contributor plus Script Manager.
  • Codesign/Team ID visibility for each target vendor updater (obtained locally with codesign -dv --verbose=4 against a known-good installed copy of the app).
  • A pilot Smart Group of no more than 10 machines for the first deployment cycle. Blast radius for the full fleet push should never exceed one site or one department per change window.

#Implementation Steps

  1. Step 1 — Identify the updater’s Team ID and executable label. Action: on a reference Mac with the target app installed, run codesign -dv --verbose=4 "/Applications/Google Chrome.app/Contents/Frameworks/Google Chrome Framework.framework/Versions/Current/Helpers/GoogleUpdater.app" and note the TeamIdentifier value. Expected result: a single Team ID string is returned (for example EQHXZ8M8AV for Google). Evidence to capture: terminal output saved to the change ticket.
  2. Step 2 — Build the Background Task Management payload. Action: create a new Configuration Profile in Jamf Pro containing the com.apple.servicemanagement payload with a Rule entry scoped by TeamIdentifier (not by literal Label string, since vendors rename LaunchAgent labels across versions far more often than they rotate signing identities). Expected result: profile validates with no XML errors in Jamf Pro’s payload preview. Evidence to capture: screenshot of the payload editor and the exported .mobileconfig attached to the change record.
  3. Step 3 — Scope to pilot only and deploy. Action: scope the profile to the 10-device pilot Smart Group, distribute via the standard MDM push (no user interaction required because the payload is enforced, not requested). Expected result: profiles show -type enrollment on a pilot Mac lists the new payload under installed profiles within one check-in cycle. Evidence to capture: command output from at least two pilot machines.
  4. Step 4 — Confirm background item approval without a prompt. Action: force a relaunch of the updater helper (kill and let launchd respawn it, or reboot) and check System Settings > General > Login Items & Extensions. Expected result: the vendor’s updater is listed as allowed with no toggle interaction and no notification banner shown to the user. Evidence to capture: a screen recording or the sfltool dumpbtm output showing the item’s approval state as allowed.
  5. Step 5 — Deploy the version-drift Extension Attribute. Action: add the script below as a Jamf Pro Extension Attribute of data type String, running at every inventory update. Expected result: inventory record populates a version string per Mac. Evidence to capture: Jamf Pro inventory search showing populated values across the pilot group.
1#!/bin/bash
2# Extension Attribute: reports installed vs pinned target version for a managed app
3APP_PATH="/Applications/Google Chrome.app"
4TARGET_VERSION="127.0.6533.100"
5
6if [ ! -d "$APP_PATH" ]; then
7  echo "<result>NOT_INSTALLED</result>"
8  exit 0
9fi
10
11INSTALLED_VERSION=$(defaults read "$APP_PATH/Contents/Info.plist" CFBundleShortVersionString 2>/dev/null)
12
13if [ "$INSTALLED_VERSION" = "$TARGET_VERSION" ]; then
14  echo "<result>CURRENT:$INSTALLED_VERSION</result>"
15else
16  echo "<result>DRIFT:$INSTALLED_VERSION</result>"
17fi
18exit 0

Expected output captured in Jamf Pro inventory: DRIFT:126.0.6478.61 for any Mac that has fallen behind, or CURRENT:127.0.6533.100 for compliant machines.

  1. Step 6 — Build the drift Smart Group. Action: create a Smart Computer Group with the criterion Extension Attribute “Chrome Version Status” like DRIFT. Expected result: group membership updates automatically after each inventory submission with no manual review. Evidence to capture: Smart Group membership count trend over 72 hours.
  2. Step 7 — Attach an automated remediation policy. Action: create a Jamf Pro Policy scoped to the drift Smart Group, trigger set to Recurring Check-in, frequency Once per week, that silently installs the latest signed PKG for the app. Expected result: on next check-in, drifted machines silently receive the current installer and drop out of the Smart Group automatically once the Extension Attribute re-evaluates as CURRENT. Evidence to capture: policy log showing “Completed” status and a before/after inventory diff.
  3. Step 8 — Wire up a drift-duration alert. Action: use the Jamf Pro API to poll the Smart Group membership on a schedule and post to a webhook if any device remains in drift beyond 24 hours (see script below). Expected result: a Slack message naming the specific device and duration. Evidence to capture: the Slack message and the corresponding API response payload.
1import requests
2import datetime
3
4JAMF_URL = "https://yourinstance.jamfcloud.com"
5TOKEN = "REPLACE_WITH_BEARER_TOKEN"
6SMART_GROUP_ID = 145
7SLACK_WEBHOOK = "https://hooks.slack.com/services/REPLACE/REPLACE/REPLACE"
8
9headers = {"Authorization": f"Bearer {TOKEN}", "Accept": "application/json"}
10resp = requests.get(
11    f"{JAMF_URL}/JSSResource/computergroups/id/{SMART_GROUP_ID}",
12    headers=headers,
13    timeout=15
14)
15resp.raise_for_status()
16data = resp.json()
17members = data.get("computer_group", {}).get("computers", [])
18
19if members:
20    names = ", ".join(m["name"] for m in members)
21    payload = {
22        "text": f"Update drift alert {datetime.date.today()}: {len(members)} Mac(s) still outdated - {names}"
23    }
24    slack_resp = requests.post(SLACK_WEBHOOK, json=payload, timeout=15)
25    slack_resp.raise_for_status()
26else:
27    print("No drift - nothing to report")

Expected output when run manually: either No drift - nothing to report printed to console, or a Slack message similar to Update drift alert 2024-06-10: 2 Mac(s) still outdated - LAPTOP-A102, LAPTOP-B217.

Stopping App Update Tickets: Automating Background Task Approval architecture diagram 2

#Verification and Expected Evidence

  • Run profiles show -type enrollment on a sample of pilot Macs and confirm the com.apple.servicemanagement payload UUID matches the one deployed from Jamf Pro. Evidence: exported command output attached to the change ticket.
  • Run sfltool dumpbtm and confirm the target Team ID’s helper shows an approval state without any “pending user approval” flag. Evidence: text output stored with the pilot sign-off.
  • Confirm the Extension Attribute reports CURRENT for all pilot machines within one policy cycle after the drift policy runs. Evidence: Jamf Pro Advanced Computer Search exported as CSV, timestamped before and after.
  • Confirm zero end-user prompts appeared during the entire cycle by checking Console.app logs for tccd or UserNotificationCenter entries referencing the updater bundle ID during the test window. Evidence: filtered Console export.

#Rollback

If the payload causes unexpected behaviour (for example, a vendor updater that legitimately needs user consent for a different reason, or a Team ID collision with an unwanted helper), unscope the Configuration Profile from the affected Smart Group immediately. Removing the profile via Jamf Pro triggers an MDM RemoveProfile command; confirm removal with profiles show -type enrollment showing the payload UUID absent within one check-in cycle. Concurrently disable the remediation Policy by removing its scope rather than deleting it, so the change is reversible without losing the Extension Attribute history. Do not delete the Extension Attribute itself — leave it running in read-only monitoring mode so drift visibility is preserved during the investigation.

#Failure and Escalation Conditions

  • Monitoring signal: Smart Group membership count for the drift group, plus the Slack webhook alert volume, both tracked daily.
  • Rollback trigger: any pilot device shows a user-facing approval prompt after the profile has confirmed installed, or the remediation policy fails on more than one pilot device with the same error code.
  • Wake a human technician when: more than 5 percent of the in-scope fleet remains in the drift Smart Group for longer than 72 hours after the remediation policy has run at least twice, or when the Jamf Pro API call in Step 8 returns a non-200 status three times consecutively (indicating a token expiry or API outage masking real drift).
  • Escalate to L3 when: the codesign Team ID for a vendor updater changes unexpectedly (detected via a failed Rule match after a vendor update), since this requires re-validating trust before widening the profile scope again.

#Measuring Ticket Deflection

Baseline the current ticket category (for example, “Software – Update Failure” or “App Not Updating”) for four weeks before rollout to establish an average weekly volume. After full-fleet deployment, track three numbers side by side: the ticket count in that category, the average Smart Group drift-group membership size, and the number of Slack escalation alerts fired. A successful rollout should show ticket volume trending toward zero within two patch cycles while the drift group median dwell time (time from joining the group to dropping out again) stays under 24 hours. Export both data sets monthly and present the ticket-volume delta against the automation coverage percentage (number of managed apps with a Background Task Management rule versus total managed apps) to justify extending the pattern to the next vendor updater.

Evidence trail

Sources and verification

Primary documentation and external technical references used in this article.

  1. 01Apple's Service Management framework documentationdeveloper.apple.com
  2. 02Apple Platform Deployment Guidesupport.apple.com
  3. 03Jamf Pro documentation on Smart Groupslearn.jamf.com
  4. 04Jamf Pro documentation on Extension Attributeslearn.jamf.com
Isla Morgan

Isla Morgan

Ops Playbook Architect

Isla Morgan is the macOS Platform Engineering Editor for The Ops Playbook, specialising in the design and day-to-day operation of secure, scalable enterprise Mac fleets.

Published
View Profile
Reader Interaction

Comments

Add a thoughtful note on Stopping App Update Tickets: Automating Background Task Approval. Comments are checked for spam and held for moderation before appearing.

Loading comments...
Comment submission is disabled until Cloudflare Turnstile keys are configured.

Learn More About KBY

Was this useful?

Operate smarter, with fewer recurring tickets.

Receive new operational playbooks, incident-prevention guidance, automation scripts and recovery runbooks.