
The one MDM key macOS 27 gives you for XProtect
Every file access permission you could manage on a Mac last year, you can still manage. Apple added one more, which its own release notes say may be denied by default, and routed it through a channel whose only documented lever is a coarse switch over configuration data as a whole, in a payload macOS 27 removes.
There is exactly one key in Apple's device management schema that mentions XProtect.
It is EnableXProtectMalwareUpload, it lives in the com.apple.systempolicy.control payload, it arrived in macOS 15.0, and Apple describes it as preventing Gatekeeper from prompting the user to upload blocked malware to Apple.
That is the whole surface. One boolean, governing telemetry.
macOS 27 also enforces a file access policy against third-party application data, and Apple ships a policy artifact of that shape as XProtect configuration data. Apple documents no key for that in either mechanism.
The search, so you can run it yourself
I went through apple/device-management on both branches, along with the declarative management declarations that are replacing the profile payloads. The pre-release seed_OS_27_0 branch is the one that matters, because it is the macOS 27 schema rather than the shipping one. It was re-checked on 2026-09-04 at commit b018018, Apple's "Seed8", committed 2026-09-02.
Case-insensitive, across the whole repository, on the seed branch at b018018. Occurrences and files are counted separately, because they are different numbers and conflating them is how a search table stops being checkable.
| Search term | Occurrences | Files |
|---|---|---|
XProtect | 1 | 1, com.apple.systempolicy.control |
Gatekeeper | 8 | 2, com.apple.systempolicy.control and com.apple.systempolicy.rule |
AppProtection | 0 | 0 |
sandbox | 0 | 0 |
quarantine | 0 | 0 |
notariz | 0 | 0 |
AppData | 1 | 1, the TCC profile, SystemPolicyAppData only |
AppDataDetailed | 0 | 0 |
Search for Detailed on its own and you get 3 hits, all ordinary English in unrelated payloads ("detailed information about a device"). The string that matters is AppDataDetailed, and that returns nothing.
The com.apple.systempolicy.control payload was otherwise unchanged in 27. The only diff against 26 is the addition of an examples: block.
Apple's own CHANGES.md in the seed branch enumerates what is new in macOS 27, and it spreads new payload keys across five sections rather than one. The new declarative configurations are accessibility settings, app settings, content-cache settings, extensible SSO, seven network declarations (dns-proxy, dns-settings, relay, and four VPN declarations) and a web content filter plugin. The new payload keys are AllowVisualIntelligence, Calendar app keys, two ProfileAssetReference entries, UninstallBehavior, a Safari privacy key, AllowSiriAI and ForceReduceSensitiveContent. The keys named above are drawn from the declarative and profile sections. The rest are two PlatformSSO keys, two login-window keys, a return-to-service key in each of the check-in and erase schemas, and three setup-assistant skip keys. Nothing app-data related is in any of the five.
The key that looks like a counter-example
There is a key called SystemPolicyAppData, and if you search the schema for app data you will find it before you find anything else. It lives in com.apple.TCC.configuration-profile-policy and Apple describes it as specifying the policies for an app to access the data of other apps.
It is not the answer, for two reasons.
It arrived in macOS 14.0, and its schema block is byte-identical between the release branch and the macOS 27 seed branch. Nothing about it is new. That is suggestive rather than decisive on its own, because an existing key can be made to govern new behavior, and further down this post a pre-existing Full Disk Access grant does exactly that to this protection. What rules it out is the service name, below. The two copies of the payload file are not identical overall. Most of that delta is editorial, rewordings and an added examples block. Two parts of it are not. There is deprecation metadata on five sensor services, Accessibility, BluetoothAlways, Camera, Microphone and SpeechRecognition. And the Accessibility content: string was rewritten, from a line saying the profile's grant capability would be removed in macOS 27.0 to one describing a non-blocking notification the user can override, which is the softened admin-grant removal this post returns to further down. The file access service list did not move, and the SystemPolicyAppData block itself is byte-identical between the two.
More decisively, it is not the service that denies you. The runtime denial on the new protection cites kTCCServiceSystemPolicyAppDataDetailed, a distinct service, and that string appears in zero Apple sources: not in the schema on either branch, not in the release notes, not in the Endpoint Security documentation, not in the entitlements index, not in the Platform Security guide. SystemPolicyAppData is a per-app PPPC grant. It is not a control over the policy.
I tested that distinction rather than leaving it as an assertion, because it is the obvious objection and the whole post turns on it.
On a macOS 27 VM, build 26A5416b, a root process holding no Full Disk Access was denied on ~/Library/Application Support/Google/Chrome. The log names the service being checked. The excerpt spans more than the single denial described above, so the middle line names a different application:
sandboxd: checking kTCCServiceSystemPolicyAppDataDetailed on path "<private>", user interaction not allowed
sandboxd: TCC denied kTCCServiceSystemPolicyAppDataDetailed for org.mozilla.firefox
kernel: (Sandbox) System Policy: perl(608) deny(1) file-read-data /Users/admin/Library/Application Support/Google/Chrome
tccd carries kTCCServiceSystemPolicyAppData and kTCCServiceSystemPolicyAppDataDetailed as separate constants, and the second one is new.
I checked that rather than assuming it. strings against tccd and sandboxd finds kTCCServiceSystemPolicyAppData on macOS 15.4.1 (24E263) and on macOS 26.6.1 (25G76), and finds no AppDataDetailed on either. On macOS 27, build 26A5416b, both are present. The same grep finds the sibling constant in the same binary on the same run, so the absence is a result rather than a search that missed. Strictly, this says the constant is absent from the versions measured, not from every point release of 15 and 26.
The PPPC payload defines 24 service keys and the list is identical between the release branch and seed_OS_27_0. SystemPolicyAppData is one of them. SystemPolicyAppDataDetailed is not there at all.
So the answer is not that you picked the wrong grant. Apple documents no grant to pick: nothing in the published payload names the service this enforcement checks.
Be precise about what that establishes, because the difference matters. It is an absence from Apple's published schema. It is not a demonstration that tccd refuses a profile carrying the undocumented key, and I could not run that demonstration: all three routes to applying a live grant are closed on an unmanaged Mac. SIP blocks writing TCC.db, profiles install is gone from macOS 27, and a throwaway VM has no MDM to enroll against. Installing the profile by hand through System Settings is not a fourth route: Apple's schema marks the PPPC payload allowmanualinstall: false and userapprovedmdm: true, so a hand-installed copy is not honored. If you can deliver a profile naming SystemPolicyAppDataDetailed from a real MDM and it takes, that would narrow this finding, and I would rather hear it than be right.
Reguła published this error verbatim in July. There is a second reason it could not work even if the key existed. The service takes an indirect object: a request from a process with no app bundle fails before authorization is even considered, with kTCCServiceSystemPolicyAppDataDetailed access requires indirect object have an associated app bundle. The authorization is keyed to a pair, the process reading and the app whose data is being read. The payload's only indirect-object mechanism is AEReceiverIdentifier, which belongs to AppleEvents. No file access service has an equivalent.
What does work, and why it is not a fix
Full Disk Access. On the same build, same binary and same paths, the root daemon without it is denied and an ssh session holding kTCCServiceSystemPolicyAllFiles reads every protected folder. The image grants that to /usr/libexec/sshd-keygen-wrapper. Those two captures also differ in host, euid and session type, so the run that actually isolates the grant is sudo-ssh.txt: root, inherited Full Disk Access, ALLOW. That is the comparison the argument rests on.
That is the useful half of the finding. The protection is TCC-gated and it is defeatable, but the one lever that defeats it hands over every protected file on the machine rather than the single app-data folder your tooling actually needed. Full Disk Access as a workaround for a backup agent or an inventory script is a real answer and a bad trade.
Apple documents the same conclusion
I went looking for a counter-argument to that and found the opposite. Apple's own macOS 27 release notes carry this, as radar 184660124:
"In the Files & Folders pane, a process without a bundle ID cannot be granted access to specific app data containers or app group containers owned by other developer teams."
The listed workaround is one sentence long:
"Consider if the access is necessary. If required, grant Full Disk Access to the process for the duration of the requirement."
That is the vendor stating, in a release note rather than a policy document, that a process without a bundle ID cannot be given scoped access to another team's app data, and that the way through is Full Disk Access. A shell script has no bundle ID. Neither does a launch daemon, a backup agent invoked as a binary, or most inventory tooling.
So the measurement above is not a finding that contradicts Apple. It is the documented behavior, reached from the other direction, and the part worth arguing about is not whether it works this way but whether "grant Full Disk Access for the duration of the requirement" is a reasonable thing to ask of a fleet.
While quoting the release notes, one correction to how this feature gets summarized, including by an earlier draft of this post. Apple's XProtect note, radar 178668601, hedges twice:
"XProtect may now restrict access to app data that is commonly targeted by malicious software. Accessing files created by other developer teams' apps may be denied by default but may be managed by the user in Privacy & Security settings."
The flat version, "denied by default and can be managed by the user", is a different note, radar 161835690, about app data containers and app group containers generally. The two get merged easily and they do not carry the same force. Where this post describes the XProtect behavior it uses Apple's modality, not the stronger one.
Worth knowing before you go looking: on macOS 27 the profiles command line tool can no longer install anything. It returns "profiles tool no longer supports installs." Profiles arrive from MDM or through System Settings, and nowhere else.
Apple's flagship security documentation says the same thing by omission. In the August 2026 edition of the Apple Platform Security guide, XProtect occurs 31 times. Cross-reference all 31 against MDM, device management, configuration profile and administrator within a three-line window and the only hit is one incidental "security software and administrators" passage on p.122. Nothing that tells an administrator what to do about it. The app data protection feature appears in neither the added nor the updated topic list of that edition: the additions are Terminal and script protections, SharePlay security, Search on iCloud.com security and Nearby sharing security, and the updates are Intro to Apple platform security, Data Protection overview, Microsoft Windows on an Intel-based Mac with a T2 chip, Tap to Pay on iPhone and Access using Apple Wallet. Apple dates that entry to the month rather than the day, so there is no publication date to measure an interval against; the survey ran on 2026-08-16 and the counts here were re-derived from the live PDF on 2026-09-06.
The part that is easy to get wrong
The tempting story here is that Apple is pulling privacy administration away from administrators and handing it to users. That story is partly false, and writing it would be the kind of overreach that gets corrected in public within a day.
Three separate things happened in macOS 27, and they point in different directions.
Sensor permissions contracted. Five services carry deprecated: '27.0' in the PPPC payload: Camera, Microphone, Accessibility, SpeechRecognition and BluetoothAlways. Deprecated is not removed, so the loss is prospective rather than already in force. Four of them reappear in the declarative PermissionDefaults key, matched on the permission rather than on the spelling, since BluetoothAlways appears there as Bluetooth, and what an administrator can express there is a suggestion rather than a setting. For each of those four the value list is None and Allow, with no deny; Apple's own wording is that the defaults "allow an organization to suggest a set of privacy permissions for use with an app", the user is shown a consent prompt, and choosing "Not Now" ignores them. Three further limits come from the schema itself. PermissionDefaults sits under the Privacy key, whose macOS entry reads allowed-scopes: [user], so on a Mac it reaches the user channel and only the user channel. The declaration is supervised-only. And Apple states that "Only AppKit-based apps on macOS support this feature." SpeechRecognition does not reappear at all: PermissionDefaults carries nine properties, OrganizationJustification, Accessibility, Bluetooth, Camera, Dictation, LocalNetwork, Location, LocationAccuracy and Microphone, and none of them is a speech-recognition service. Dictation is a different service, not a rename. That is a genuine contraction, and it is the one everybody noticed.
Binary execution control expanded, substantially. AllowedBinaries and DeniedBinaries land in 27 with CDHash, TeamID, SigningID, PathPrefix and SigningState matching, and both carry allowed-scopes: [system] on macOS, so they reach the system channel where the contraction above reaches only the user. That is native, Santa-class binary allowlisting, and it is a new administrator power that did not exist before. It lands in the very same declaration as the contraction above.
Apple even reversed course inside the beta cycle. The plan to remove admin grant capability for Accessibility was softened in Seed5 to notify-the-user-and-let-them-override. Admin grant still works. That is not the behavior of a vendor uniformly stripping administrator control.
File access did neither. Not one file-system TCC service was deprecated or removed. You keep SystemPolicyAllFiles. You keep the folder services. You keep SystemPolicyAppBundles and SystemPolicyAppData. Every file access class you could manage in 26, you can still manage in 27.
Then a new file access protection appeared, guarding third-party app data, which Apple's own release notes say may be denied by default, with no key in either mechanism.
That is the finding. Not a retreat, not an expansion. A new member of a category where every existing member has an administrator key, shipped without one, through a channel built for malware signatures.
The policy is already on your macOS 26 Macs
There is one more measurement, and it changes when this becomes your problem rather than what the problem is.
The policy artifact Apple delivers is not part of the operating system. Apple ships it as XProtect configuration data, which is the same channel that carries malware signatures, and that channel updates independently of the OS. So I went and looked on a machine running macOS 26.6.1 (25G76), which had XProtect configuration data 5358:
$ shasum -a 256 /var/protected/xprotect/XProtect.bundle/Contents/Resources/AppProtectionPolicy.plist
2d715412ad6611a072314bbfe04bb4446c1879b5522d19da7a989a2aad96b7a6
That is the same hash as the copy measured on macOS 27 build 26A5416b. The same 4,351-byte policy file, byte for byte, is sitting on both operating systems.
On the macOS 26.6.1 host I measured, none of the markers macOS 27 carries for this mechanism are present:
$ sysctl -a | grep -i appprotection
(no output)
$ sysctl security.mac.sandbox.appprotection.version
sysctl: unknown oid 'security.mac.sandbox.appprotection.version'
$ strings -a /usr/libexec/sandboxd | grep -i AppProtection
(no output)
On macOS 27 build 26A5416b that sysctl returns defaultRules-3, and strings on sandboxd returns AppProtection constants.
A negative result is worth exactly what its control is worth, so here is the control. The same strings invocation on that same macOS 26 binary does find constants of the shape I am claiming are absent:
$ strings -a /usr/libexec/sandboxd | grep kTCCServiceSystemPolicy
kTCCServiceSystemPolicyAllFiles
kTCCServiceSystemPolicyAppData
kTCCServiceSystemPolicySysAdminFiles
Three siblings found, zero AppProtection strings. The binary is readable and the grep works.
So the artifact ships ahead of the machinery that acts on it. On the macOS 26.6.1 host I measured, I found nothing that can read it. If you are on macOS 26, Apple is delivering that policy file down the same pipe as malware definitions. On the host I measured it was present, current, and had nothing to read it. The machinery that acts on a policy of this shape arrives with the OS upgrade, not with an overnight XProtect push, and the upgrade is a thing you schedule. That is more warning than these changes usually come with, and it is worth spending rather than discovering.
One thing the delivered file does not settle: it declares version defaultRules-1, while the ruleset in force on build 26A5416b reports defaultRules-3, and sandboxd looks for a differently named file, AppProtectionRules.plist, which is not there. So on the builds I measured, macOS 27 is enforcing a ruleset compiled into sandboxd, not the one Apple is shipping down the channel. The channel is live; whether anything is reading it yet is not established.
The scope, because this is one measurement: one host, one build, arm64, read once. It establishes the absence of this mechanism on 26, not that some different mechanism does not protect those paths by another route. I did not measure which XProtect version first delivered the file to 26, and I did not check macOS 15 for it at all.
The strongest argument against writing any of this down
The absence may be deliberate, and there is a good case that it should be.
A per-app exemption to read another application's data is, described honestly, a capability to read another application's data. Any key that let an administrator grant it would also let anyone who reached that administrator's MDM grant it, silently, to a binary of their choosing. Apple does not give administrators an override for malware definitions either, and nobody files that as a gap. On that reading the missing key is the design working, and the correct response is to fix the tooling that wanted the exemption rather than to ask for the lever.
I think that argument is largely right, and it does not change the finding. Whether the absence is deliberate is a question about Apple's intent. Whether your permission review can see the policy is a question about your process, and the answer to the second one is no regardless of the answer to the first. A control you cannot enumerate is a control you cannot audit, and "it is enforced correctly by default" is a thing you are believing rather than a thing you are checking. The argument for the missing key being correct is also an argument that you will never be told when it changes.
Why the channel matters more than the policy
The policy travels as XProtect configuration data. That is the same pipe that carries Yara signature updates, and it is version-independent of the OS build.
The administrator lever aimed at that pipe is not specific to this policy. ConfigDataInstall, in the com.apple.SoftwareUpdate domain, is documented only as restricting the automatic installation of configuration data. Apple's payload reference does not say the malware feed and the app data policy are the same configuration data. Its sibling CriticalUpdateInstall, ten lines above it in the same file, is the one whose description names a System Settings option, "Install system data files and security updates"; the ConfigDataInstall description names none. I have not tested either against this channel. There is a further wrinkle, and it cuts the same way as everything else here. On macOS 27 that payload is gone. Apple's schema at the commit pinned above marks com.apple.SoftwareUpdate as deprecated: '26.0' and removed: '27.0', and points administrators at the declarative com.apple.configuration.softwareupdate.settings configuration instead, which carries no equivalent of ConfigDataInstall.
What matters for this post is narrower. The only documented lever aimed at this pipe was a coarse switch over configuration data as a whole, it is removed in the release this post is about, and Apple's payload reference never said the malware feed and the app data policy are the same configuration data. Whether flipping it on macOS 26 actually stops this policy arriving is a measurable question, and it is the subject of a separate write-up rather than something to assert here.
What I will not claim
I did not find this mechanism first and I am not going to imply otherwise. Wojciech Reguła of SecuRing published it on 2026-07-16, extracted the ruleset out of sandboxd, and named the same defaultRules-2 version string I measured independently a month later in a VM. Michael Tsai aggregated the coverage on 2026-07-24 and Howard Oakley has been tracking the XProtect side since 2026-08-05. The mechanism is documented. What I have not seen anyone write is that it has no administrator key and that the absence is invisible from inside the schema, which is what this post is about.
The policy file's own key names, allowedTeamId, allowedSigningIds and allowedPlatformSigningIds, appear in zero Apple sources as spelled. Not in apple/device-management on either branch, not in the macOS 27 release notes, not in the Endpoint Security documentation, not in the entitlements index, not in the Platform Security guide. Search case-insensitively, as above, and allowedTeamId does collide as a substring with Apple's unrelated AllowedTeamIdentifiers, 5 hits across 2 files on the release branch, in com.apple.system-extension-policy and com.apple.syspolicy.kernel-extension-policy. Different key, different subsystem. The other two return nothing under any search.
They exist only in the plist dumped off disk. There is no Apple-documented schema for AppProtectionPolicy.plist, so anything anybody tells you about how those keys resolve, including me, is inference from an undocumented binary format.
I also enumerated every com.apple.security.* and com.apple.developer.* identifier in Apple's entitlements index, 163 of them when I ran it; Apple revises that index, so treat the count as the size of the survey rather than a figure to re-derive today. There is no documented entitlement by which a signed helper is granted access to another team's application data. One candidate looked promising and was ruled out on reading: com.apple.developer.app-migration.data-container-access is iOS and iPadOS only, is scoped to the extension's own containing app, and is a one-time cross-platform migration mechanism rather than a cross-team grant.
Whether a third-party Endpoint Security client is exempt is still open. It needs an entitlement Apple has to approve, and I have not tested it. Do not let anyone tell you it is settled.
What to do with this
- Look at what your permission review is built from. If the input is an export of your configuration profiles, or a list of what your MDM can set, it structurally cannot contain this policy. That is not a gap in your process so much as a gap in the map your process reads.
- Write down the channel, not just the policy. The durable version of this finding is not "there are eight guarded folders." It is that XProtect configuration data is now a policy delivery channel whose only documented control was a coarse switch over configuration data as a whole, with no per-policy visibility, and macOS 27 removes the payload that carried it. The folder list will change. The channel is the thing to track.
- Do not reach for
ConfigDataInstallas the fix. It is coarse by design, what else goes quiet when you flip it is a measurable question I have not measured, and on macOS 27 it is not there to flip: Apple marks the payload that carries it removed in 27.0 and ships no declarative equivalent. On macOS 26, check it before you rely on it.
Method and artifacts
The schema work is a set of searches against public repositories and documentation, retrieved 2026-08-16 and re-run on 2026-09-04 against a fresh clone of both branches, the seed branch pinned at commit b018018, committed by Apple on 2026-09-02. Every query string is in the post so the negative results are reproducible rather than asserted. The 2026-09-04 pass was a re-run rather than a re-reading of the earlier survey, and it corrected four numbers in the draft: the Gatekeeper count, which had reported files as occurrences; the count of new network declarations in CHANGES.md; a claim that the TCC payload was byte-identical across branches, when only its file access service list is; and a search on Detailed where the checkable string is AppDataDetailed.
The claim that kTCCServiceSystemPolicyAppDataDetailed is new was measured rather than assumed, by running strings against tccd and sandboxd on macOS 15.4.1 (24E263) and macOS 26.6.1 (25G76) and comparing against the macOS 27 VM. The sibling constant kTCCServiceSystemPolicyAppData is present on all three, which is what makes the absence of the second one a result rather than a failed search.
Enforcement behavior was measured first-hand in disposable Tart VMs on 2026-08-17 and re-measured 2026-08-18 with zero drift on the same build, macOS 27 26A5388g, in-force ruleset defaultRules-2. A re-vet on 2026-08-19 reproduced the headline behavior on build 26A5416b, developer beta 6 in the build history cited below, where the in-force ruleset had moved to defaultRules-3. As of 4 September 2026 the newest macOS 27 build is beta 8, 26A5425a, seeded 31 August; no release candidate has shipped and macOS 27 has not reached general availability. 26A5416b is nonetheless the newest macOS 27 build available as a public prebuilt VM image: the image both tags of ghcr.io/cirruslabs/macos-golden-gate-vanilla resolve to is one manifest published 2026-08-18 and unchanged since. So the enforcement claims here are measured on the newest build that is publicly testable, not merely on the newest one that happened to be lying around, and testing a later beta would mean building an image from an Apple installer. Where this post makes a claim about enforcement rather than about documentation, it is scoped to the build named beside it. The schema findings do not carry that limitation; they are current as of Apple's 2026-09-02 commit.
XProtect configuration data stands at version 5358, released 2026-09-02. The two updates since the measurement, 5357 on 2026-08-26 and 5358 on 2026-09-02, are Yara signature changes. Neither reports a change to the app data protection mechanism.
Sources
Schema and documentation sources retrieved 2026-08-16 against the pinned Seed5 commit, then re-confirmed 2026-09-04 against the seed_OS_27_0 branch at commit b018018 (Seed8, committed 2026-09-02). Enforcement behavior measured first-hand in disposable VMs on 2026-08-17 and 2026-08-18, with the root-denial run in evidence/pppc-exemption-2026-09-04/ and the delivered-but-inert measurement in evidence/enforcement-gap-2026-09-05/, with a re-vet on 2026-08-19. Every search in this post is reproducible against public sources and the exact query strings are given.
- Apple: device-management schema repository, com.apple.systempolicy.control payload, EnableXProtectMalwareUpload (macOS 15.0)
- Apple: macOS 27 release notes: radar 178668601, XProtect "may now restrict access to app data that is commonly targeted by malicious software", access "may be denied by default but may be managed by the user in Privacy & Security settings"; and radar 184660124, a process without a bundle ID cannot be granted access to specific app data containers, with the documented workaround being to grant Full Disk Access
- Apple: Apple Platform Security guide, August 2026 edition, revision history and XProtect occurrences
- Apple: Apple Platform Security guide, the August 2026 PDF edition the occurrence counts and the p.122 passage were derived from
- Howard Oakley: What just changed in XProtect? 2026-08-07
- Howard Oakley: XProtect update to 5356, 2026-08-18
- Howard Oakley: major XProtect update, 2026-08-05, the start of the tracking this post credits
- Howard Oakley: XProtect update to 5357, 2026-08-26, Yara-only
- AppleDB: macOS 27.0 build history, newest build beta 8 `26A5425a` seeded 2026-08-31, no release candidate
- Apple: device-management schema, PPPC payload marked allowmanualinstall false and userapprovedmdm true
- Howard Oakley: XProtect update to 5358, 2026-09-02, Yara-only, current version at time of writing
- Apple: device-management schema at seed_OS_27_0 commit b018018, com.apple.SoftwareUpdate payload deprecated 26.0 and removed 27.0
- Apple: Entitlements index, the enumeration of com.apple.security.* and com.apple.developer.* identifiers
- Wojciech Reguła (SecuRing): first public documentation of the mechanism, ruleset extracted from sandboxd, 2026-07-16
- Michael Tsai: aggregation of the Golden Gate Application Support protection coverage, 2026-07-24