Normal view

There are new articles available, click to refresh the page.
Before yesterdayMain stream

Biden Sues Justice Dept. to Block Release of Tapes

28 May 2026 at 00:45
The former president argued that the Justice Department has a responsibility to protect the privacy of conversations he had with a former ghostwriter.

© Doug Mills/The New York Times

Recordings of conversations former President Joseph R. Biden Jr. had with his ghostwriter came into the Justice Department’s possession in 2023.

Control what gets written to the log

By: hoakley
30 April 2026 at 14:30

One of the first things that strikes you when you look at a log extract from a Mac, is the number of entries that have some or all of their contents censored with <private>. Another is the sheer number of entries; even when your Mac is doing little, there’s a constant stream of them. This article explains how you can get control of both.

Logging preferences

The keys to controlling what gets written to the log in macOS are property lists stored inside /Library/Preferences/Logging. By default you’re likely to see few files there, which may include a high-level policy in com.apple.system.logging.plist. If present, that’s likely to set just two keys, Enable-Logging to true, and Locked to true as well. But that property list doesn’t tell the whole story.

To discover full top-level policy, you need to enter the command
sudo log config --status
which is likely to return
System mode = INFO

Step one down from there with
sudo log config --status --subsystem com.apple.system.logging
and that might report
INFO PERSIST_DEFAULT
or could extend to include
SIGNPOST_PERSISTED_OFF SIGNPOST_ENABLED_ON SIGNPOST_BACKTRACE_ENABLED_OFF OVERSIZE_ENABLED_OFF
as well.

Now try a more specific subsystem with
sudo log config --status --subsystem com.apple.network
and you’re likely to see something similar, unless there’s a property listed named com.apple.network.plist in the Subsystems folder there, in which case it should reflect the settings in that.

Those settings largely concern two features:

  • Levels of log entry recorded, set as default, info or debug. The first of those includes all entries of default or higher level, the second of info, default or higher, and the third of debug, info, default or higher. Default global level is normally info, so that debug entries don’t appear in the log.
  • Whether the entries are saved to persistent storage (disk), using the same hierarchy of levels.

Thus INFO PERSIST_DEFAULT means that all log entries of info level and above, but not debug, will be collected, and the default setting is used to determine which get written to disk.

Apple explains those basic settings in man log, and its documentation for developers.

Signpost and Oversize settings aren’t explained there, but are in man 5 os_log. Signpost log entries are intended for use by developers to assess performance, and are rarely of any use to others. Oversize log entries can be many pages long, and are stored separately when enabled.

Controlling logging preferences

There are three ways to control logging preferences, which all converge on those same property lists:

  • The log config command, as used above. This is quick and simple, but limited, and perhaps best used to check effective settings for individual subsystems and processes.
  • Write your own property lists and install them in the appropriate folder in /Library/Preferences/Logging. Although this is powerful, as there’s limited guidance on what can be included, you’ll probably want to start from existing property lists. There’s further information in Peter Steinberger’s post and man 5 os_log.
  • Install a custom log profile, which you can also use as a model to develop your own property lists and profiles.

Custom logging preferences take effect almost immediately, and don’t require restarting, but they only apply to log entries written once they have been applied, never retrospectively.

Limiting log entries by level

As the Unified log discards old log entries to constrain the space occupied by the logs, the only way to extend the period covered by stored log entries is to limit the rate at which fresh entries are added to the log. You can do this by careful assessment of which subsystems are writing most entries, and changing their logging preferences.

However, that only applies when there’s an excess of log entries at debug or info levels. When there is, adding or modifying the preferences for that subsystem to store entries at a level of default or info should extend the period they cover. Be cautious, though: that excess of entries could reflect a problem, and by excluding them you may well conceal its cause and extent.

Custom log profiles

The simplest alternative is to install a Configuration Profile containing the saved settings to be applied to the property lists in /Library/Preferences/Logging. I provide a signed profile to remove all that <private> censorship in enablelogprivatedata.

To install the profile unzip the archive into a convenient folder and double-click it. You’ll be prompted to review the profile to install it.

Open System Settings > General & Device Management, and inspect it by double-clicking the profile there.

Click on the Install button to accept and install the profile.

To remove it, select the profile and click the – tool below.

If you watch the contents of com.apple.system.logging.plist in /Library/Preferences/Logging you’ll see that change, with the setting of the key Enable-Private-Data to true. If you then run
sudo log config --status
with that profile installed, it should report something like
System mode = INFO PRIVATE_DATA
to confirm that private data is being shown in log entries, and that’s the best way to gain access to their full contents. Remember to remove the profile as soon as you’re done, or your log will continue to leak sensitive data.

There’s a collection of custom log profiles to gather log extracts about specific features in macOS (and Apple’s other OSes). Although they’re listed here, you can only download them if you have a developer (or equivalent) account with Apple. What’s more, Apple describes these as confidential, and explicitly forbids their use or disclosure without its permission. So much as I’d love to explain the undocumented features they use, I regret that I can’t.

The MACL extended attribute

By: hoakley
21 April 2026 at 14:30

Apple silently introduced the com.apple.macl extended attribute in macOS Catalina, as part of its new ‘privacy by user intent’ protection, as detailed here. Its first public mention came in October 2019, when Quinn “The Eskimo!” revealed its purpose and the fact that it contained a two-byte header of 01 00 and a UUID associated with the app that obtained access ‘by intent’.

It next caught the eye of Jeff Johnson, who described it in detail on 18 December 2019. It was he who first reported its most obvious problem: “It turns out that the com.apple.macl extended attribute is governed by System Integrity Protection, so the only way to delete it is to disable SIP, or boot into another volume and delete it from there. Thus, once you implicitly grant special access to a file, you can’t easily revoke that special access.”

It was soon associated with other problems: “open a PDF in Preview without saving it, and it will be given a quarantine flag but no com.apple.macl xattr. If you try to Save that to overwrite the original document, Preview promptly refuses, and may not even be able to write that file out under another name.”

Further details of how this MACL xattr are involved in privacy protection were given by Adam Chester in October 2020. He again described the contents as consisting of a two-byte header, incremented by now to 02 00, followed by a UUID representing the app with permission to access the file, and pointed out that UUID is “unique for each system, user and application”.

Armed with a way of generating an endless supply of MACL xattrs using my test app Insent, and a little crawling through xattrs using xattred, I set out to get further details of what they now contain and their life cycle.

Header

Their two-byte header follows one of two patterns:

  • the first byte incrementing from 01 (2019) to 08 (2025) over time, as if a version number, followed by either 00 or 40.
  • the first byte 00, followed by 43, 81 or C1.

These appear to determine the effect of the MACL, for example 08 00 granting access to a protected directory for listing its contents, and read access to files within it.

UUID

All UUIDs seen in MACL xattrs are version 4, so have largely random content, and are saved in binary form. As far as I’m aware, no one has yet discovered how to identify the app identified by these UUIDs, other than by finding another MACL xattr with the same, known app association. This is made more complex by the fact that the same app is identified by different UUIDs in different sessions, as explained below. As a result, once a Mac has restarted, there’s no way to match previous UUIDs with the apps they identified.

Presentation

Each header-UUID pair is packed consecutively in time order, the most recent last in the xattr, into blocks of four, totalling 72 bytes, with trailing space padded by zeroes, making the size of each MACL xattr a multiple of 72. The great majority of them consist of only 72 bytes.

Life cycle

Each new header and UUID is written to the xattr at the time that the kernel grants access to that directory or file, and apparently remains there indefinitely, with more recent header-UUID pairs being appended at the end.

Currently, in macOS 26.4, each app’s UUID is unique to that session, and restarting that Mac ensures the app will subsequently be identified using a different UUID. This may be the result of tokens used by the sandbox being invalidated on rebooting, as described by Adam Chester.

For example, here are the header-UUID pairs associated with Insent in three consecutive sessions, taken from the same MACL xattr on the ~/Desktop directory:

  • 0800 BF6F283B-2179-4155-AA30-FAA4C4B7ACBE
  • 0800 03475E10-B904-447A-87F0-641B3F61B377
  • 0800 86522100-DF0A-4AD2-BE42-F98A28374ECC

Within each session, each MACL xattr written for Insent to three different directories was the same.

MACL xattrs are still protected by SIP, in that any attempt to remove the xattr results in it being restored immediately.

The effect is that grants of access by intent were invalidated by restarting the Mac, as the previous UUID was no longer recognised as corresponding to Insent. Previous criticism that this special access persisted and couldn’t be revoked has been addressed, albeit crudely, as that does require restarting.

Summary

  • The com.apple.macl extended attribute was introduced in macOS Catalina to enable ‘privacy by user intent’.
  • Each record in the xattr consists of a two-byte header followed by a UUID.
  • Records are stored consecutively, most recent last, in 72-byte blocks with trailing zero padding in the last block, when necessary.
  • The header can have either of two forms, one starting with a version number from 01 to 08, followed by 00 or 40. The other form starts with 00, followed by 43, 81 or C1.
  • The UUID identifies the app granted access via the MACL xattr, but an app’s UUID changes after a restart, limiting tracking.
  • Currently, because restarting results in changed UUIDs, access granted by user intent should also be reset after a restart.
  • MACL xatrrs can’t be removed directly by the user as they’re protected by SIP.

Privacy: How locations are protected

By: hoakley
20 April 2026 at 14:30

Ten days ago, I drew attention to anomalies in privacy protection of locations that could mislead, in that Privacy & Security settings could claim an app didn’t have access to a protected folder when it did. This article proposes an explanation, and provides further details of protected locations and their behaviour. This is based on my test app Insent version 1.2, which you can use to explore these behaviours in the comfort of your own Mac.

Procedures

For the avoidance of any doubt, Insent is a simple macOS app that doesn’t run in an App Sandbox, doesn’t have any entitlements, but is notarized. Its two features of greatest interest here are Open by consent, and Open from folder buttons:

  • Open by consent constructs a folder path as a string without involving user action in an Open and Save Panel, then calls FileManager.default.contentsOfDirectory() to list files within that folder. If that’s successful, it randomly selects a text file from those, opens it, and displays the opening part of the text contents. This is opening that file by consent, as the app is given access to that folder by user consent through TCC’s privacy controls, by consenting to the standard dialog.
  • Open from folder displays an Open and Save Panel (NSOpenPanel) asking the user to select a folder. The URL returned from that is then used to call FileManager.default.contentsOfDirectory() to list files within that folder. If that’s successful, it randomly selects a text file from those, opens it, and displays the opening part of the text contents. This is opening that file by user intent, as the user has chosen that folder to be used. As a result, this doesn’t invoke TCC’s privacy controls.

Consent

The mechanism used to list the contents of a protected folder and open a file from among those is the more obvious, and better documented. Even though the app itself isn’t running in an App Sandbox, the call is intercepted by sandboxd and passed to TCC for it to check whether current privacy policy for that app should allow the request. TCC first checks whether kTCCServiceSystemPolicyAllFiles applies, with the app being given Full Disk Access. If it does, then sandboxd is advised and the call to list the directory proceeds.

If kTCCServiceSystemPolicyAllFiles doesn’t apply, TCC checks for the location-specific service, including

  • kTCCServiceSystemPolicyDesktopFolder
  • kTCCServiceSystemPolicyDocumentsFolder
  • kTCCServiceSystemPolicyDownloadsFolder
  • kTCCServiceSystemPolicyRemovableVolumes
  • kTCCServiceSystemPolicyNetworkVolumes
  • kTCCServiceFileProviderDomain.

If that has been given, sandboxd is advised and the call proceeds.

If neither of those applies, then a standard consent dialog will be displayed. If the user allows that, then the location-specific service is granted, and sandboxd advised to proceed. As these steps are all documented in detail in the log, there’s no difficulty in following them there, and diagnosing their problems.

Intent

Although the log contains details of the use of the Open and Save Panel to select a folder, when a protected folder is listed by intent, there are no informative log entries at all. For example,
0.812549 Insent sendAction:
0.812607 Insent: trying to list files in /Users/hoakley/Desktop
0.813297 Insent: trying to look in /Users/hoakley/Desktop for text files
0.813373 Insent: trying to read from: /Users/hoakley/Desktop/00vlutest1pm.text
1.173727 Insent: read from: /Users/hoakley/Desktop/00vlutest1pm.text

where the first four are written consecutively in the log.

To understand what’s going on here we have to consider how sandbox behaviour might apply. This has been explained clearly for the App Sandbox by Mark Rowe, and the most relevant section there is about Mandatory Access Control in the kernel, towards the end: “The macOS kernel (XNU) provides a Mandatory Access Control Framework (MACF) that exposes around 300 policy hooks that can be used to approve or deny specific operations at a fine-grained level. Most of the policy hooks correspond to specific system calls or operations on the kernel’s file system abstraction (VFS). As the name implies, these policy hooks are mandatory and are applied to all clients that use the system calls or perform file system operations.”

So when Insent calls FileManager.default.contentsOfDirectory() to list files within a folder, its corresponding policy hook is called with a context including the directory and the caller.

This is where the next component comes into play: any com.apple.macl extended attribute saved to that directory. We still know remarkably little about those xattrs, despite them being so common. Here I turn to Adam Chester’s early account of how they’re used for protection by user intent. These Mandatory Access Control Lists (MACL) enable the sandbox to determine whether the request to list the contents of the directory should be approved. Because this all takes place within the kernel and its sandbox extension, no entries appear in the log.

The only evidence of this happening is the MACL xattr saved to the protected directory, and making sense of that isn’t easy. Each MACL is 72 bytes, and multiple MACLs can be concatenated into a single xattr as necessary. They’re protected by SIP, so can’t be stripped in place while that’s enabled.

Because this mechanism remains within the kernel and sandbox, it’s invisible to TCC, and to its controls in Privacy & Security. If an app has gained access to a protected location by intent, then that takes precedent over TCC’s controls, and results in the contradiction seen in Files & Folders, whereby access is disabled but still takes place. This isn’t a bug, but a feature of access by intent.

Mechanisms

The following diagram summarises how I think these two mechanisms operate.

For the sake of simplicity, I have omitted the final step between access being granted/denied by the sandbox, and the app, where of course it’s the kernel that either permits the app’s request for the operation, or blocks it and returns an error. (I’m grateful to Csaba Fitzl for drawing my attention to that.)

This explains why Apple has been so reluctant to document any of this, and why MACLs are so opaque. If an app were capable of creating its own functional MACLs, they would enable it to bypass TCC’s controls and gain access to any protected location. Unfortunately, the side effect is that TCC isn’t allowed insight into what the sandbox is up to, and there’s no transparency for the user.

Overview

Even using a known and simple app like Insent, behaviours aren’t always consistent, and are susceptible to order effects and maybe even cosmic rays! There are also subtle differences between protected locations that can make generalisation unreliable. However, after extensive checks with Insent the following table gives an overview of protected locations in macOS 26.4.

The three common local folders ~/Desktop, ~/Documents and ~/Downloads are most consistent, with controlled read access, GUI controls in Files & Folders, and can be overridden by intent using MACL xattrs. Network volumes also appear to protect write access.

External volumes that are mounted automatically during startup don’t appear to count as being removable, but any that are mounted later have similar protection for both read and write, and can be overridden by intent using MACLs.

iCloud Drive and third-party cloud storage using the FileProvider API are more difficult to investigate, as I’ve still been unable to find any GUI control. It also doesn’t appear to be overridden by intent using MACLs, although its directories can still have com.apple.macl xattrs attached to them.

In addition to using any controls in Files & Folders, all TCC controls can be reset using tccutil, for example in
tccutil reset All co.eclecticlight.Insent
and that takes immediate effect, without a restart.

Restarting may be the best and perhaps only way (without disabling SIP) to reset MACLs. Although they can appear to persist at times, and the xattrs themselves don’t change, Adam Chester points out that tokens used by the sandbox are invalidated on rebooting, so maybe existing MACLs may not remain effective following a restart.

Privacy: Which folders are protected in Tahoe?

By: hoakley
15 April 2026 at 14:30

Obtaining a definitive list of locations that are subject to privacy protection in macOS Tahoe 26.4 hasn’t been easy, and I’ve previously relied on information given piecemeal in WWDC sessions. This article reports the results of formal testing using a new version of my test app Insent, and brings some surprises.

Insent version 1.2 now allows you to set the path to the folder to be used for its Save and Open by consent buttons, using a Combo box. That’s a combination of a popup menu including the three most popular locations, Desktop, Documents and Downloads, and an editable text box into which you can enter a custom folder path.

Save and Open by consent are actions in which the user doesn’t express their intent to write to or read from the protected location, for example in an Open and Save Panel, but the app’s code determines the path and file. Thus, to ensure the app’s access doesn’t compromise the user’s privacy, those actions may be blocked unless the user gives their consent in a dialog presented for TCC, the privacy manager.

In the Save by consent code, all Insent does is construct a URL to a new text file in that folder path, then tries writing a String to that URL using String.write() non-atomically. To open a text file from that folder path, it attempts to enumerate the contents of the directory at that URL using FileManager.default.contentsOfDirectory(), then iterates through the contents until it finds a text file to open. If it does, it tries to read that file using String(contentsOf: url), and displays the start of that String.

Only three locations conform to the standard control:

  • ~/Desktop
  • ~/Documents
  • ~/Downloads

In each case, there is no control over writing to the location, but any attempt to list the contents of that folder elicits a request for consent, and results in an entry for Insent in the Files & Folders list in Privacy & Security settings.

For iCloud Drive, and presumably third-party cloud services with equivalent privacy protection, there is no control over writing to the location, and listing folder contents requires consent, but no entry appears in the Files & Folders list, and I have been unable to discover any equivalent control elsewhere. Thus, once consent has been given, it appears to remain indefinitely, as the user doesn’t have a control to disable that access.

Removable Volumes and Network Volumes differ again, in that both Save and Open by consent require user consent, although giving consent to one action also grants it for the other. However, not all removable volumes are treated as protected. A Time Machine backup drive that is mounted automatically during startup, and has an additional volume not used for backups, wasn’t given any protection, while an SSD connected and mounted well after login was treated as a Removable Volume.

Although often listed as being subject to privacy protection, read access by consent was blocked for Time Machine backups, and they’re read only anyway.

One strange behaviour discovered during testing was the automatic addition of Insent to the Full Disk Access list, rather than individual Files & Folders. However, Full Disk Access hadn’t been granted, and when Insent was removed from that list, individual Files & Folders were shown instead.

There was no evidence of any other special locations among other standard folders in the user’s Home folder, although there are separate controls covering Photos access, and that to app databases, as listed in Privacy & Security settings.

The following table summarises privacy protection for special locations in macOS 26.4.

Insent version 1.2 is now available from here: insent12
Have fun trying to make sense of this protection.

Explainer: sandboxes

By: hoakley
11 April 2026 at 15:00

For a computer to be really secure, it mustn’t run any untrusted code. In macOS that would mean banning all third-party apps, which would severely limit the usefulness of a Mac. One way round this is to run all untrusted code in a tightly restricted environment, denying it the ability to access memory, storage or other resources outside those dedicated to it by its sandbox, managed by macOS.

Even that’s too restrictive for the vast majority of apps. You expect an image editor to be able to open and save images in folders you control, such as ~/Documents, those in your Pictures folder or Photos Library. So having put an app into its sandbox, the next thing you need to do is provide it ways to ease some of those restrictions. In Apple’s operating systems, those are granted according to entitlements burned into the app’s signature.

Considering our hypothetical sandboxed image editor, those entitlements are likely to include com.apple.security.files.user-selected.read-write, giving the app read and write access to files the user has selected in a standard macOS Open or Save dialog.

This overlaps with privacy protection controlled by TCC. The standard user folder for images is ~/Pictures, so to gain read and write access to that the app needs an entitlement for com.apple.security.assets.pictures.read-write as well. Then there’s the desire to gain direct access to any built-in or external camera to capture movies and still images, requiring com.apple.security.device.camera, another entitlement overlapping with those to protect privacy.

What started off as an app running entirely within its sandbox is gradually being allowed to do more, and that sandbox is becoming less effective as the app gains access to more outside resources. Although this might appear increasingly pointless, balanced compromises can be reached that limit an app’s attack surface without frustrating users.

Apple requires all apps distributed through its App Store to run in their app sandbox, something marked in the app by another entitlement com.apple.security.app-sandbox, and explained here.

macOS also applies sandbox features to apps that aren’t marked to be run in a sandbox, most notably to implement privacy protection. By default, when any app tries to list the contents of a protected folder, the sandbox blocks that unless the privacy controller TCC authorises access. Unfortunately that can lead to complex interactions between sandboxing and TCC.

The Finder and other bundled utilities in macOS don’t reveal the entitlements claimed by sandboxed apps, indeed they don’t even tell you whether an app runs in a sandbox in the first place, a curious omission. For that you’ll need a third-party tool such as Mothers Ruin’s Apparency. Some sandboxed apps have such long lists of entitlements that they seem allowed to do almost anything, and you might wonder how effective that sandbox would be at preventing malicious behaviour from affecting your Mac.

Entitlements aren’t necessarily an indicator that an app is sandboxed, either: com.apple.security.app-sandbox is the tell-tale sign. Apple also uses entitlements to grant access to certain restricted features in macOS, like snapshots. Look at the entitlements of apps like Carbon Copy Cloner that have access to snapshots and you’ll see com.apple.developer.vfs.snapshot there for that purpose, even though that app isn’t sandboxed.

Because entitlements, including that to sandbox the app, are burned into an app’s signature, the only way to remove any of them is to strip the app’s signature altogether, and remove the whole lot. You would then have to re-sign the app using an ad hoc signature, and you’re pretty well guaranteed that your doctored app won’t run at all. So there’s no practical way out of sandboxing and entitlements for those apps requiring them.

Another distinctive feature of a sandboxed app is its named container folder, in ~/Library/Containers, where its sandboxed storage is located. An app’s container is created automatically by macOS when that app is run for the first time, but isn’t cleaned up when the app is removed, so can become orphaned and merit careful manual removal.

As App Store apps have to be sandboxed, but notarized apps supplied outside the App Store don’t, it might be tempting to see them as alternatives, or complementary to one another, but they’re very different. A few apps like BBEdit are both sandboxed and notarized, but that’s usually even harder than it sounds, and quite an accomplishment when it works well. But the restrictions of the sandbox make it impossible for many apps to do their jobs, so there will always be a need for those that don’t run in a sandbox.

Why you can’t trust Privacy & Security

By: hoakley
10 April 2026 at 14:30

In this Friday’s magic demonstration, I’m going to show how what you see in Privacy & Security settings can be misleading, when it tells you that an app doesn’t have access to a protected folder, but it really does.

Although it appears you can achieve this using several ordinary apps, to make things simpler and clearer I’ve written a little app for this purpose, Insent, available from here: insent11

I’m working in macOS Tahoe 26.4, but I suspect you should see much the same in any version from macOS 13.5 onwards, as supported by Insent.

For this magic demo, I’m only going to use two of Insent’s six buttons:

  • Open by consent, which results in Insent choosing a random text file from the top level of your Documents folder, and displaying its name and the start of its contents below. As it does this without involving the user in the process, the macOS privacy system TCC requires it to obtain the user’s consent to list and access the contents of that protected folder.
  • Open from folder, which opens an Open and Save Panel where you select a folder. Insent then picks a random text file from the top level of that folder, and displays its name and the start of its contents below. Because you expressed your intent to access that protected folder, TCC considers that is good enough to give access without requiring any consent.

Demonstration

Once you have downloaded Insent, extracted it from its archive, and dragged the app from that folder into one of your Applications folders, follow this sequence of actions:

  1. Open Insent, click on Open by consent, and consent to the prompt to allow it to access your Documents folder. Shortly afterwards, Insent will display the opening of one of the text files in Documents. Quit Insent.
  2. Open Privacy & Security settings, select Files & Folders, and confirm that Insent has been given access to Documents.
  3. Open Insent, click on Open by consent, and confirm it now gains access to a text file without asking for consent. Quit Insent.
  4. Open Privacy & Security settings, select Files & Folders, and disable Documents access in Insent’s entry there using the toggle.
  5. Open Insent, click on Open by consent, and confirm that it can no longer open a text file, but displays [Couldn't get contents of Documents folder].
  6. Click on Open from folder and select your Documents folder there. Confirm that works as expected and displays the name and contents of one of the text files in Documents.
  7. Click on Open by consent, and confirm that now works again.
  8. Confirm that Documents access for Insent is still disabled in Files & Folders.
  9. Whatever you do now, the app retains full access to Documents, no matter what is shown or set in Files & Folders.

Indeed, the only way you can protect your Documents folder from access by Insent is to run the following command in Terminal:
tccutil reset All co.eclecticlight.Insent
then restart your Mac. That should set Insent’s privacy settings back to their default.

You can also demonstrate that this behaviour is specific to one protected folder at a time. If you select a different protected folder like Desktop or Downloads using the Open from folder button, then Insent still won’t be able to list the contents of the Documents folder, as its TCC settings will function as expected.

How does this work?

Insent is an ordinary notarised app, and doesn’t run in a sandbox or pull any clever tricks. When System Integrity Protection (SIP) is enabled some of its operations are sandboxed, though, including attempts to list or access the contents of locations that are protected by TCC.

When you click on its Open by consent button, sandboxd intercepts the File Manager call to list the contents of Documents, as a protected folder. It then requests approval for that from TCC, as seen in the following log entries:
1.204592 Insent sendAction:
1.205160 Insent: trying to list files in ~/Documents
1.205828 sandboxd request approval
1.205919 sandboxd tcc_send_request_authorization() IPC

TCC doesn’t have authorisation for that access by Insent, either by Full Disk Access or specific access to Documents, so it prompts the user for their consent. If that’s given, the following log entries show that being passed back to the sandbox, and the change being notified to com.apple.chrono, followed by Insent actioning the original request:
3.798770 com.apple.sandbox kTCCServiceSystemPolicyDocumentsFolder granted by TCC for Insent
3.802225 com.apple.chrono appAuth:co.eclecticlight.Insent] tcc authorization(s) changed
3.809558 Insent: trying to look in ~/Documents for text files
3.809691 Insent: trying to read from: /Users/hoakley/Documents/asHelp.text
3.842101 Insent: read from: /Users/hoakley/Documents/asHelp.text

If you then disable Insent’s access to Documents in Privacy & Security settings, TCC denies access to Documents, and Insent can’t get the list of its contents:
1.093533 com.apple.TCC AUTHREQ_RESULT: msgID=440.109, authValue=0, authReason=4, authVersion=1, desired_auth=0, error=(null),
1.093669 com.apple.sandbox kTCCServiceSystemPolicyDocumentsFolder denied by TCC for Insent
1.094007 Insent: couldn't get contents of ~/Documents

If you then access Documents by intent through the Open and Save Panel, sandboxd no longer intercepts the request, and TCC therefore doesn’t grant or deny access:
0.897244 Insent sendAction:
0.897318 Insent: trying to list files in ~/Documents
0.900828 Insent: trying to look in ~/Documents for text files
0.901112 Insent: trying to read from: /Users/hoakley/Documents/T2M2_2026-01-06_13_03_00.text
0.904101 Insent: read from: /Users/hoakley/Documents/T2M2_2026-01-06_13_03_00.text

Thus, access to a protected folder by user intent, such as through the Open and Save Panel, changes the sandboxing applied to the caller by removing its constraint to that specific protected folder. As the sandboxing isn’t controlled by or reflected in Privacy & Security settings, that allows TCC, in Files & Folders, to continue showing access restrictions that aren’t applied because the sandbox isn’t applied.

Conclusion

Access restrictions shown in Privacy & Security settings, specifically those to protected locations in Files & Folders, aren’t an accurate or trustworthy reflection of those that are actually applied. It’s possible for an app to have unrestricted access to one or more protected folders while its listing in Files & Folders shows it being blocked from access, or for it to have no entry at all in that list.

Is this likely to occur?

Most apps that want access to protected folders like Documents appear to seek that during their initialisation, and before any user interaction that could result in intent overriding the need for consent. However, many users report that apps appear to have access to Documents but aren’t listed in Files & Folders, suggesting that at some time that sequence of events does occur.

To be effectively exploited this would need careful sequencing, and for the user to select the protected folder in an Open and Save Panel, so drawing attention to the manoeuvre.

Most concerning is the apparent permanence of the access granted, requiring an arcane command in Terminal and a restart in order to reset the app’s privacy settings. It’s hard to believe that this was intended to trap the user into surrendering control over access to protected locations. But it can do.

I’m very grateful to Richard for drawing my attention to this.

Privacy: Files & Folders or Full Disk Access?

By: hoakley
8 April 2026 at 14:30

Alongside RunningBoard, TCC and privacy protection are among the greatest contributors to the Unified log, although they’ve been a little less loquacious more recently. This article sheds light on what they do when an app tries to access the contents of a protected folder. Log extracts were obtained from Insent 1.1 running in macOS 26.4 on a Mac mini M4 Pro, and concentrate on what happens when Insent tries to ‘open by consent’, first listing the contents of ~/Documents, then picking a text file at random and displaying some of its contents.

Relevant entries from the log are given in the Appendix at the end of this article.

Accessing ~/Documents by consent

When the Open by consent button is clicked, Insent first tries to obtain a listing of the Documents folder. That request is considered to be sandboxed, so the sandbox service requests authorisation to proceed from TCC.

When it receives that request from sandboxd, TCC first checks whether the requesting app has been granted Full Disk Access, formally the kTCCServiceSystemPolicyAllFiles service. An early step in that sequence is to establish the attribution chain, so TCC can check the correct process, in this case Insent’s executable code.

A second check is then started, to determine whether the requesting app has been granted the more restricted service of kTCCServiceSystemPolicyDocumentsFolder. Those requests are followed by many validation checks on the Insent executable.

The simplest outcome is that Insent has kTCCServiceSystemPolicyAllFiles, in which case access is granted to the sandbox, and the Documents folder is listed as requested.

If Insent doesn’t have that, TCC considers kTCCServiceSystemPolicyDocumentsFolder:

  • if that has already been granted, TCC tells the sandbox to grant access;
  • if that has neither been granted nor denied, TCC displays the dialog requesting user consent, and acts accordingly;
  • if that had been granted but has been disabled (denied) in Privacy & Security, TCC denies access without seeking any consent.

This demonstrates an important difference in the behaviour of Full Disk Access (kTCCServiceSystemPolicyAllFiles) and locations protected by Files & Folders (here kTCCServiceSystemPolicyDocumentsFolder). Disabling Full Disk Access doesn’t deny access, it just doesn’t enable it. Disabling a specific protected location in Files & Folders will deny that app access to that location.

If you want to return an app’s Files & Folders settings to the default, so you will be prompted to consent for access, you therefore need to remove that app’s entry from Files & Folders, and might also need to log out and back in, or restart, to ensure that’s put into effect.

These are summarised in the diagram above. For the sake of simplicity, access granted under SystemPolicyAllFiles isn’t shown separately, but merged with that under SystemPolicyDocumentsFolder.

Interactions between Full Disk Access and individual access in Files & Folders can appear complicated, even random at times, but are actually the result of logical decisions. They are also reflected faithfully in Privacy & Security settings. For example:

  • Remove all settings for Insent from both Files & Folders and Full Disk Access.
  • Open Insent, click on Open by consent, and agree to add the app to Files & Folders with Documents access.
  • Quit Insent, and disable its Documents access in Files & Folders but don’t remove it. Then add Insent to the Full Disk Access list.
  • Confirm that Open by consent still functions correctly, because its Full Disk Access setting overrides Files & Folders, as shown in the latter settings. Quit Insent.
  • Remove Insent from the Full Disk Access list, and it will be listed in Files & Folders with access to Documents disabled once again.

Summary

  • If the app at the head of the attribution chain has been given Full Disk Access, access to list and read files will be given.
  • If not, then location-specific access in Files & Folders will be applied.
  • If there’s no setting for that app and location, the user is asked for consent.
  • If that app has already been given consent for that location, access to list and read files will be given.
  • If that app has consent denied or disabled, access to list and read files will be denied.
  • None of these controls apply to access by user intent in a File Open dialog, or to writing files.

Open and Save Panel access

As I have made clear, when a user expresses their intent to open a file by selecting it using the Open and Save Panel, that doesn’t trigger the same system of access rules. However, the request is still considered by TCC, this time using the Attribution Chain to examine the app rather than that panel service.

When looking briefly at log entries for that sequence, I noticed something odd: instead of the TCC access request being made for a location-related policy such as SystemPolicyDocumentsFolder, it’s recorded as kTCCServiceScreenCapture. Whether that’s a bug or intended behaviour, the request was authorised, and access proceeded.

The first time I saw that, I was so surprised that I repeated the test using Insent to confirm that I wasn’t misunderstanding the log entries. Exactly the same happened a second time, despite Insent having nothing whatsoever to do with making screenshots.

Previously

Consent, intent and privacy
Privacy: protected folders

Appendix: Log Extracts

Each entry is prefaced with the clock time in seconds.

Request, dialog and approval:

In this case, Insent hadn’t made any prior request to access the Documents folder in that session, so had no entry in Privacy & Security settings. When its access dialog was displayed, consent was granted, allowing access to proceed. As with other extracts, this starts with the event marking the button click in Insent.

1.204592 Insent sendAction:
1.205160 Insent: trying to list files in ~/Documents
1.205828 sandboxd request approval
1.205919 sandboxd tcc_send_request_authorization() IPC
1.206291 com.apple.TCC SEND: 0/7 synchronous to com.apple.tccd.system: request: msgID=440.94, function=TCCAccessRequest, service=kTCCServiceSystemPolicyAllFiles,
1.207414 com.apple.TCC AttributionChain: accessing={TCCDProcess: identifier=co.eclecticlight.Insent, pid=2232, auid=501, euid=501, binary_path=/Applications/Insent.app/Contents/MacOS/Insent}, requesting={TCCDProcess: identifier=com.apple.sandboxd, pid=440, auid=0, euid=0, binary_path=/usr/libexec/sandboxd},
1.235893 com.apple.TCC SEND: 0/7 synchronous to com.apple.tccd: request: msgID=440.95, function=TCCAccessRequest, service=kTCCServiceSystemPolicyDocumentsFolder,

[TCC then makes various checks on Insent]
1.261591 com.apple.TCC AUTHREQ_PROMPTING: msgID=440.95, service=kTCCServiceSystemPolicyDocumentsFolder, subject=Sub:{co.eclecticlight.Insent}Resp:{TCCDProcess: identifier=co.eclecticlight.Insent, pid=2232, auid=501, euid=501, binary_path=/Applications/Insent.app/Contents/MacOS/Insent},
1.265001 com.apple.TCC No usage string found (key:NSDocumentsFolderUsageDescription) for client[2232] in bundle:[private]
1.265006 com.apple.TCC display_prompt: called for [private] for service kTCCServiceSystemPolicyDocumentsFolder

[The access dialog is displayed, and consent given]
3.798770 com.apple.sandbox kTCCServiceSystemPolicyDocumentsFolder granted by TCC for Insent
3.802225 com.apple.chrono appAuth:co.eclecticlight.Insent] tcc authorization(s) changed
3.809558 Insent: trying to look in ~/Documents for text files
3.809691 Insent: trying to read from: /Users/hoakley/Documents/asHelp.text
3.842101 Insent: read from: /Users/hoakley/Documents/asHelp.text

Request after approval:

In this case, Insent had already been granted consent to access the Documents folder, as recorded in Privacy & Security settings.

0.911529 Insent sendAction:
0.912220 Insent: trying to list files in ~/Documents
0.913379 sandboxd request approval
0.913482 sandboxd tcc_send_request_authorization() IPC
0.913953 com.apple.TCC SEND: 0/7 synchronous to com.apple.tccd.system: request: msgID=440.100, function=TCCAccessRequest, service=kTCCServiceSystemPolicyAllFiles,
0.915394 com.apple.TCC AttributionChain: accessing={TCCDProcess: identifier=co.eclecticlight.Insent, pid=2255, auid=501, euid=501, binary_path=/Applications/Insent.app/Contents/MacOS/Insent}, requesting={TCCDProcess: identifier=com.apple.sandboxd, pid=440, auid=0, euid=0, binary_path=/usr/libexec/sandboxd},
0.949736 com.apple.TCC SEND: 0/7 synchronous to com.apple.tccd: request: msgID=440.101, function=TCCAccessRequest, service=kTCCServiceSystemPolicyDocumentsFolder,

[TCC then makes various checks on Insent]
0.970955 com.apple.TCC AUTHREQ_RESULT: msgID=440.101, authValue=2, authReason=2, authVersion=1, desired_auth=0, error=(null),
0.971072 com.apple.sandbox kTCCServiceSystemPolicyDocumentsFolder granted by TCC for Insent
0.973350 Insent: trying to look in ~/Documents for text files
0.973532 Insent: trying to read from: /Users/hoakley/Documents/piklisting.text
1.035508 Insent: read from: /Users/hoakley/Documents/piklisting.text

Request denied:

In this case, Insent had previously been given access to the Documents folder, but that was then disabled.

1.033344 Insent sendAction:
1.034069 Insent: trying to list files in ~/Documents
1.035189 sandboxd request approval
1.035299 sandboxd tcc_send_request_authorization() IPC
1.035820 com.apple.TCC SEND: 0/7 synchronous to com.apple.tccd.system: request: msgID=440.108, function=TCCAccessRequest, service=kTCCServiceSystemPolicyAllFiles,
1.037404 com.apple.TCC AttributionChain: accessing={TCCDProcess: identifier=co.eclecticlight.Insent, pid=2303, auid=501, euid=501, binary_path=/Applications/Insent.app/Contents/MacOS/Insent}, requesting={TCCDProcess: identifier=com.apple.sandboxd, pid=440, auid=0, euid=0, binary_path=/usr/libexec/sandboxd},
1.071652 com.apple.TCC SEND: 0/7 synchronous to com.apple.tccd: request: msgID=440.109, function=TCCAccessRequest, service=kTCCServiceSystemPolicyDocumentsFolder,

[TCC then makes various checks on Insent]
1.093533 com.apple.TCC AUTHREQ_RESULT: msgID=440.109, authValue=0, authReason=4, authVersion=1, desired_auth=0, error=(null),
1.093669 com.apple.sandbox kTCCServiceSystemPolicyDocumentsFolder denied by TCC for Insent
1.094007 Insent: couldn't get contents of ~/Documents

Open and Save Panel Oddity:

In this case, the Open from folder button in Insent was used to select the Documents folder, ready to allow the app access by intent. This extract shows what happened after the button in the Open and Save Panel was clicked.

8.800555 com.apple.appkit.xpc.openAndSavePanelService trackMouse send action on mouseUp
8.802062 com.apple.appkit.xpc.openAndSavePanelService tcc_send_request_authorization() IPC
8.802140 com.apple.TCC SEND: 0/7 synchronous to com.apple.tccd.system: request: msgID=2259.2, function=TCCAccessRequest, service=kTCCServiceScreenCapture,
8.802469 com.apple.TCC AttributionChain: responsible={TCCDProcess: identifier=co.eclecticlight.Insent, pid=2255, auid=501, euid=501, responsible_path=/Applications/Insent.app/Contents/MacOS/Insent, binary_path=/Applications/Insent.app/Contents/MacOS/Insent}, requesting={TCCDProcess: identifier=com.apple.appkit.xpc.openAndSavePanelService, pid=2259, auid=501, euid=501, binary_path=/System/Library/Frameworks/AppKit.framework/Versions/C/XPCServices/com.apple.appkit.xpc.openAndSavePanelService.xpc/Contents/MacOS/com.apple.appkit.xpc.openAndSavePanelService},
8.809596 com.apple.TCC Handling access request to kTCCServiceScreenCapture, from Sub:{co.eclecticlight.Insent}Resp:{TCCDProcess: identifier=co.eclecticlight.Insent, pid=2255, auid=501, euid=501, responsible_path=/Applications/Insent.app/Contents/MacOS/Insent, binary_path=/Applications/Insent.app/Contents/MacOS/Insent}, ReqResult(Auth Right: Unknown (None), promptType: 1,DB Action:None, UpdateVerifierData)
8.809609 com.apple.TCC AUTHREQ_RESULT: msgID=2259.2, authValue=1, authReason=5, authVersion=1, desired_auth=0, error=(null),

Privacy: protected folders

By: hoakley
7 April 2026 at 14:30

On Sunday I introduced some of the principles involved in the protection of folders, to preserve your privacy, and provided a small test app, Insent. This article follows on with additional concepts, details, and a new version of Insent that writes diagnostic information to the log. This article refers to privacy protection as implemented in macOS Tahoe 26.4.

The macOS privacy system is more formally known as Transparency, Consent and Control (TCC), and is built around its manager tccd, working alongside the security system and the sandbox service sandboxd. The last might surprise those who thought that sandboxing was only required for apps provided in the App Store, but this sandbox is different.

How it works

When an app makes certain types of request of the file system, including those seeking a list of files (e.g. with FileManager’s contentsOfDirectory() method), or opening a file for read access, that request is passed to sandboxd for approval. That in turn queries TCC to discover whether that app should be authorised for that access. Depending on the path to be accessed, TCC checks in its database of policy approvals, runs various safety checks on the app’s signature and other properties, then tells sandboxd whether the request should be approved or denied.

As I revealed in the previous article, TCC’s controls over folders only apply to reading their directory and file contents. If an app wants to write a file to one of those protected locations, privacy restrictions don’t apply, only conventional Posix permissions. This is easily verified using the Save buttons on the left side of Insent’s window, which can write test files wherever you as a user have sufficient privileges. This is an important distinction, and a consequence of TCC’s purposes.

Reading directory listings and file contents is also different when it’s a user intent. This is most characteristically performed using the File Open dialog, where only the user gets to see the lists of files, and has complete control over which file is opened. This is handled by a separate XPC process, the Open and Save Panel Service, which has automatic approval. The same mechanism applies to the Open Recent command, drag-and-drop, double-clicking the document, and using the Finder’s Open command.

Attribution

The Open and Save Panel Service is also an example of another fundamental concept in macOS privacy protection, that of the attribution chain.

This is often encountered when considering how privacy protection can be applied to command tools that lack a GUI that could support TCC’s dialogs. Ultimately, each process has a GUI app responsible for it, and it’s that app which TCC uses as the front-end. In the case of most command tools that are run from Terminal, the attribution chain ends in Terminal.

If you want your command tools to have Full Disk Access, you thus add the Terminal app to the list in Privacy & Security settings. The disadvantage of this design is that it gives Full Disk Access to all command tools run in Terminal’s shell, and could get you into trouble if one turns out to be flawed or malicious. This can be exploited by ClickFix attackers, which trick you into pasting malicious commands into Terminal, and is a good reason for not leaving Terminal with Full Disk Access any longer than is necessary.

Daemons or services, whose name normally ends in d, are seldom run from Terminal, and when they require Full Disk Access can be added as individual binaries, although they can’t normally be given access to individual Files & Folders.

Protected folders

I’ve been unable to discover a comprehensive and up-to-date official list of protected folders and locations, but the following appear to be those most frequently used:

  • ~/Documents
  • ~/Downloads
  • ~/Desktop
  • removable volumes
  • iCloud Drive
  • third-party cloud storage
  • network volumes
  • Time Machine backups.

The first three are by far the most common in most Macs, with Removable Volumes close behind. Others are more dependent on your hardware configuration, for example whether you use network shares or third-party cloud services.

Purpose

The overriding principle in privacy protection is to minimise access given to potentially sensitive files.

Apps that are intended to access files anywhere or everywhere, such as backup apps and those used to detect duplicate files, should normally be given Full Disk Access, as should be advised in their documentation. That requires you to put trust in them not to abuse their privilege, and in their supplier to ensure they aren’t the victim of a supply-chain attack. If you have any doubts whatsoever, don’t install that app, and certainly don’t give it Full Disk Access.

Other apps should only be given access to Files & Folders when you’re invited to give your consent in one of TCC’s dialogs, and then only if you consider the app has a sufficiently good reason to be given that access, and can be trusted not to abuse it. All this should be explained in the app’s documentation, and better apps cover it in their onboarding sequence.

The Files & Folders list is different from Full Disk Access. You pick and choose which apps to give Full Disk Access to, and can leave an app listed there but with access disabled, to ensure it will remain blocked. TCC decides which apps are offered for inclusion in the Files & Folders list on the strength of their making a request of the file system that triggers sandboxd to ask TCC if it has been approved for such access. You can’t add apps of your choice, but you can disable an access that has already been granted, and remove that app from the list.

In the next article I’ll show what happens in the log when sandboxd and TCC are in action. This has been made much easier in a new version of Insent which writes detailed entries in the log. If you want to study those, Insent 1.1 is now available from here: insent11
For those who don’t want to dive that deep, version 1.0 is the same in all other respects, and is available from here: insent10

Last Week on My Mac: Consent, intent and privacy

By: hoakley
5 April 2026 at 15:00

Privacy protection changed radically in macOS Mojave and Catalina, but in the last couple of weeks I have realised how seven years later it’s still commonly misunderstood. While most can see how it protects access to hardware resources like the camera, and app data such as calendars, when it comes to Files & Folders and Full Disk Access, many remain hopelessly lost. This compromises our privacy, as all too often we end up giving an app Full Disk Access when it doesn’t need it.

Much of this confusion is the result of inadequate explanation, or to be more blunt, total absence of information. Apple’s otherwise commendable account of privacy controls barely mentions Macs and concentrates almost exclusively on iPhones, which don’t have Full Disk Access, and whose Files & Folders control is primitive by comparison. The Platform Security Guide also has remarkably little of relevance to say. Perhaps the closest we have to a conceptual account is that given by Kelly Yancey in his section of the Advances in macOS Security presentation at WWDC19.

Perhaps the most prevalent mystery is why a user’s Documents folder should be protected, and why so many apps need to ask for access to that folder? Before answering that, we need to understand two underlying concepts, of consent and intent.

It’s precisely because the Documents folder is so popular for our documents that it needs protection. A rogue app with uncontrolled access might be able to acquire tax and financial details, as well as having access to much of your personal information. So we need control over which apps can access which files there.

When we want to open a document, we express our intent to access its contents when we open that document in a File Open dialog, using Open Recent or a similar command, or by double-clicking the document. We choose the app we trust with the document’s contents, and the document, in our intent.

When an app wants to open a document without our direct involvement there’s the danger that, no matter what the file’s permissions might say, we don’t want a page layout app looking through our tax returns. For those apps we trust to have direct access to files in our Documents folder we thus give our consent to that action. If the app asks for access and we don’t trust it, then we refuse our consent, and the app is locked out.

Thus, the only ways that an app can open documents in the Documents folder are by our intent, or by giving our consent, and those involve different processes.

To help understand this more clearly, I’ve put together a little app Insent, a portmanteau of the words intent and consent. I also thought you might appreciate the Hallowe’en pumpkin in its icon.

Here I’ll use just two of its six buttons to draw the distinction between intent and consent. Once you’ve unarchived Insent’s folder, drag the app from there to one of your Applications folders, or somewhere similar, to run it. Open the app, click through its standard notarisation dialog, and you’ll see its main window.

Insent can read and write text files with the extensions .txt or .text. Confirm that it can open one in a protected location like your Desktop or Downloads folder by clicking on its Open by intent… button at the top right. You’ll see a standard File Open dialog in which you can select and open that file, and its filename and the opening characters of that file will be shown in the text boxes below. There will be no request to give access to that protected folder (consent) as you have expressed your intent to open that file.

Next, ensure that your Documents folder has at least one text file accessible at its top level. Then click on the Open by consent button. Instead of asking you which file to open, Insent now chooses that by itself, picking a text file at random from inside your Documents folder.

You should now see this dialog requesting your consent to allow that access to go ahead. Click on the Allow button, and the filename and text will then be displayed in those two text boxes, confirming Insent was given access.

You’ll also see Insent has been added to the Files & Folders section in Privacy & Security settings, with access specifically to the Documents folder.

Confirm that control does what it claims by quitting Insent, turning access to the Documents folder off, opening Insent, and clicking on Open by consent again. Now instead of seeing the filename, you’ll see the message that Insent [Couldn't get contents of Documents folder], because you withdrew your consent.

With that privacy control still disabled, try clicking on the Save by consent… button. This writes a brief text file whose name starts with Insent followed by a UUID into your Documents folder – the same folder you’ve withdrawn consent from, and where it can’t read a text file. But if you click on Open by intent… and select that same file there, so expressing your intent to open it, it should still open normally.

These few minutes have shown:

  • Folders including ~/Documents are protected to restrict reading not writing files.
  • Apps retain the ability to read files in protected folders by user intent, when explicitly opening the file.
  • Apps themselves can only open files in protected folders with express user consent.
  • Each consent in Folders & Files is limited to the app and the protected folder.
  • Consent will be sought automatically when an app tries to access a protected folder.
  • When consent has been given and is then disabled, the app will be denied access to files in that protected folder.

So the next time you’re invited to give an app access to a protected folder, you’ll know that it’s trying to access its contents. If you don’t think that app should have free access to the files in that folder, deny that request, and don’t whatever you do be persuaded to give the app Full Disk Access just to have a quieter time, or because Support recommends it.

Insent version 1.0 for macOS 13.5 or later is available from here: insent10
and I’ll be returning to it later next week.

❌
❌