Skip to content

macOS Unified Log Triage: Queries That Matter

log show predicates and parser filters for sudo, SSH, Screen Sharing, TCC, Gatekeeper, XProtect, launch agents, login items, USB mounts and the log command.

Published on 4 min read

TL;DR. Start from processes and subsystems, not from exact message text: sudo, sshd, screensharingd, tccd / com.apple.TCC, syspolicyd, XProtect, launchd and Background Task Management, diskarbitrationd, and the log command itself. Each section below gives a log show predicate for a Mac and the equivalent filter or preset in the Unified Log Parser, which flags the same families automatically on the Findings tab.

A caution before the queries: Apple treats log messages as free text. Phrases change between releases, and a query that returns nothing is not proof of absence. Read the entries around every hit (same PID, same minute).

Privilege use: sudo and su

log show --archive case.logarchive --timezone UTC --predicate 'process == "sudo" AND eventMessage CONTAINS "COMMAND="'

Each line has the form user : TTY=ttys001 ; PWD=/Users/user ; USER=root ; COMMAND=/bin/…. Failed attempts appear as incorrect password attempt. In the parser, the Authentication preset selects sudo, su, opendirectoryd, loginwindow, authd, sshd and SecurityAgent; the sudo flag keeps only lines with a command or a failure, not the directory-lookup chatter sudo also produces.

authd records authorization rights, such as system.privilege.admin when an app asks for an administrator password, with the client that asked. The flag is Authorization rights.

Remote access: SSH and Screen Sharing

log show --archive case.logarchive --timezone UTC --predicate 'process BEGINSWITH "sshd" OR process == "screensharingd"'

Remote Login and Screen Sharing are off by default; any activity means someone enabled them. Recent OpenSSH versions split the server into sshd and sshd-session, so match both. The SSH / Screen Sharing preset covers both, plus ARDAgent for Apple Remote Desktop.

Privacy permissions: TCC

log show --archive case.logarchive --timezone UTC --predicate 'subsystem == "com.apple.TCC"'

This is verbose: every client request is logged. Focus on tccd's own decisions and on high-impact services — kTCCServiceSystemPolicyAllFiles (Full Disk Access), kTCCServiceAccessibility, kTCCServiceScreenCapture, kTCCServiceListenEvent, kTCCServicePostEvent, kTCCServiceAppleEvents. The parser's Sensitive privacy permissions flag keeps tccd decisions for those services; the plain TCC flag keeps the other requests and prompts. Granting Full Disk Access to Terminal shortly before bulk file access is a pattern worth reconstructing minute by minute. Cross-check with the TCC database itself.

Gatekeeper, quarantine and XProtect

log show --archive case.logarchive --timezone UTC --predicate 'process == "syspolicyd" OR process BEGINSWITH "XProtect" OR eventMessage CONTAINS[c] "quarantine"'

syspolicyd assesses downloaded code; most of its output is routine. The Gatekeeper decisions flag narrows to lines mentioning a block, a denial, missing notarization or a user override ("Open Anyway"). Quarantine mentions help link a file to the app that downloaded it. XProtect produces a lot of scheduled activity; the flag keeps detection and remediation wording.

Persistence: launch agents, daemons and login items

log show --archive case.logarchive --timezone UTC --predicate 'eventMessage CONTAINS "/Library/LaunchAgents/" OR eventMessage CONTAINS "/Library/LaunchDaemons/" OR subsystem == "com.apple.backgroundtaskmanagement"'

Background Task Management (macOS 13 and later) logs new login items and launch items as they are registered. Paths under ~/Library/LaunchAgents and /Library/LaunchDaemons also appear every time an existing agent starts, so expect routine hits; look for new labels and for plists named like vendors you do not have (the sample's com.example.updater.plist). The launchd / login items preset and the Launch agents, daemons and login items flag cover this.

USB devices and volumes

log show --archive case.logarchive --timezone UTC --predicate 'process == "diskarbitrationd" OR subsystem BEGINSWITH "com.apple.DiskArbitration"'

Mounts, unmounts and ejects name the volume (/Volumes/EXFIL in the sample). Pair them with file activity in the same minutes to argue that data went to a removable drive. The USB & mounts preset and the Volume mounts flag select these.

The log command itself

On recent releases the log tool records its own runs, with the parent process and arguments, under subsystem com.apple.log. An intruder running log show to check what was recorded, or sudo log erase, leaves a trace there, until the erase takes effect. The The log command flag keeps them.

Shell and scripting clues

Unified Logs are not a process-execution log, but command lines leak into messages: sh -c, osascript -e, curl -o, python -c, base64 -d, chmod +x, xattr -d com.apple.quarantine. The Shell and scripting commands flag searches for these patterns anywhere. Treat hits as leads; installers and updaters produce many.

Putting it together

Use the Findings tab for a first pass, set the time range around the first strong signal ("around this event ±1 h" from any entry), then switch to the Log tab and clear the flag filter to read everything the same processes did. The browser walkthrough does exactly this on the synthetic FIN-MBP-03 case, and the export article covers moving the results into a timeline.

Related articles

Step by step: open a macOS .logarchive, diagnostics folder or log show export in the free Unified Log Parser, triage findings, set a time range and export.
Collect macOS Unified Logs with log collect, a raw copy of diagnostics and uuidtext, UAC, Velociraptor or mac_apt, and avoid the gaps that break parsing.
Export macOS Unified Logs with log show (ndjson, json, text styles), avoid time-zone traps, compare parsers and build CSV or Timesketch timelines.