Back in March, we learned that macOS 13 Ventura had introduced a new extended attribute (xattr) for tracking the provenance of apps. At that time, evidence of how this might work was confusing, as it appeared that the xattr had changed behaviour since its introduction. Some apps were covered in provenance xattrs, while others had none at all. This article tries to describe how this xattr and provenance tracking work in macOS 13.3.1.
Provenance tracking currently consists of the
com.apple.provenance xattr, with a fixed size of 11 bytes and consisting of high order bits and an 8-byte integer primary key, and the
provenance_tracking table in /var/db/SystemPolicyConfiguration/ExecPolicy, which also stores the app’s cdhash and other information about it.
The only visible sign of provenance tracking is that single xattr, com.apple.provenance, which can be added to the app bundle folder (with the .app extension) when the quarantine flag is cleared on first run of the app. This turns out to be quite an elaborate process, best summarised in a diagram.
Consider when you download a Zip archive containing one or more documents and an app. On receipt over an unsecured network connection, either from the internet or AirDrop, two security xattrs are added to the archive on arrival: com.apple.quarantine, the quarantine flag, which is set, and an unprotected com.apple.macl xattr, for the archive as a document. That’s unprotected in the sense that it’s not protected by SIP, and can be removed.
When that Zip archive is decompressed and unarchived, any documents will inherit its set quarantine flag; as documents, that flag won’t be cleared. The app’s bundle folder also has a set quarantine flag attached.
When the app is moved to a different enclosing folder, such as Applications, and is launched for the first time using the Finder, its xattrs change: the quarantine flag is cleared but left in place, a com.apple.macl xattr that’s protected by SIP is attached, and an unprotected com.apple.provenance xattr is also attached.
If the app is first launched from the same folder that it arrived in, that works differently, and no provenance xattr will be attached. Neither are provenance xattrs attached to documents.
Entering provenance data
On app first run, once Gatekeeper has completed its evaluation of the app, and the user has approved running the app,
syspolicyd reports the creation of provenance data in the app’s entry in the ExecPolicy database:
3.296437 syspolicyd Code evaluation completed: 2
3.296574 syspolicyd Allowing code due to user approval
3.296597 syspolicyd Skipping registration as it was already registered: PST: (path: /Applications/SystHist.app), (team: QWY4LRW926), (id: co.eclecticlight.SystHist), (bundle_id: co.eclecticlight.SystHist)
3.296599 syspolicyd Updating flags: /Applications/SystHist.app, 518
3.343128 syspolicyd Created provenance data for target: TA(5a27d5b41b488128, 0), PST: (path: /Applications/SystHist.app), (team: QWY4LRW926), (id: co.eclecticlight.SystHist), (bundle_id: co.eclecticlight.SystHist)
3.343133 syspolicyd Handling provenance root: TA(5a27d5b41b488128, 0)
3.343203 syspolicyd Wrote provenance data on target: TA(5a27d5b41b488128, 0), PST: (path: /Applications/SystHist.app), (team: QWY4LRW926), (id: co.eclecticlight.SystHist), (bundle_id: co.eclecticlight.SystHist)
3.343204 syspolicyd Putting executable into provenance with metadata: TA(5a27d5b41b488128, 0)
3.343209 syspolicyd Putting process into provenance tracking with metadata: 776, TA(5a27d5b41b488128, 0)
3.343211 syspolicyd Tracking process with attributes: 776, TA(5a27d5b41b488128, 0)
Updating provenance data
On subsequent runs of that app,
syspolicyd locates the previously stored provenance data, and updates it:
0.870928 syspolicyd Adding default exception for team: QWY4LRW926
0.870951 syspolicyd Registered app bundle for protection: PST: (path: /Applications/Sparsity.app), (team: QWY4LRW926), (id: co.eclecticlight.Sparsity), (bundle_id: (null))
0.870952 syspolicyd Updating flags: /Applications/Sparsity.app, 518
0.897559 syspolicyd Found provenance data on target: TA(1b5834a7f5a56f8d, 0), PST: (path: /Applications/Sparsity.app), (team: QWY4LRW926), (id: co.eclecticlight.Sparsity), (bundle_id: (null))
0.897661 syspolicyd Putting executable into provenance with metadata: TA(1b5834a7f5a56f8d, 0)
0.897666 syspolicyd Putting process into provenance tracking with metadata: 631, TA(1b5834a7f5a56f8d, 0)
0.897668 syspolicyd Tracking process with attributes: 631, TA(1b5834a7f5a56f8d, 0)
Currently, provenance data for apps doesn’t appear to be inspected until after the app has completed its Gatekeeper checks, which could include checking its cdhashes, already stored in the ExecPolicy database. There appears to be scope for additional cdhash and other checks to be made earlier during Gatekeeper checks.
Another security feature apparently introduced in Ventura is Bastion and XProtectBehaviorService, which contain rules of behaviour that can detect behavioural violations for processes such as the Finder. One potential role for the ExecPolicy database is to track and flag such violations as potentially malicious. This would be a major departure from previous macOS security, which is based on static analysis.
I’m very grateful to Randy Saldinger of Mothers Ruin and Pico, who have contributed substantially to the information above.