TCC and the macOS Platform Sandbox Policy
Background
What is TCC?
TCC is a subsystem on macOS that is responsible for managing which applications a user has permitted to access certain resources. Its full name is "Transparency, Consent and Control". If you've ever seen an "Application" would like to access the camera prompt… that's TCC.
TCC is used to gate access to resources that Apple considers to be sensitive. Protected resources include:
- Hardware devices such as the camera and microphone
- Location services
- A user's photos, contacts, calendar, or reminders
- Files in a user's desktop, downloads or documents folders
- Data managed by other third-party applications
TCC permissions are mediated by the tccd
process that runs as part of macOS.
System frameworks that access sensitive resources use private APIs, such as
TCCAccessRequest
to determine whether they have permission to access the
resource. The API performs an interprocess call to tccd
, which will trigger a
prompt if it is the first time the application has attempted to access that
class of resource. Otherwise, it will return the stored permission decision.
What is the Platform Sandbox Policy?
For background about what sandboxing is on macOS and how it works, see Sandboxing on macOS.
The Platform Sandbox Policy is a sandbox policy that is applied to all processes running on macOS. It is applied transparently to all processes on the system, irrespective of whether they are explicitly sandboxed.
The Platform Sandbox Policy implements one part of System Integrity Protection on macOS. It defines and enforces the restrictions on access to the file system, Mach bootstrap names, IOKit devices, and other resources. Amongst other things, the platform sandbox policy uses process attributes (such as signing identity, bundle identifier, and entitlements) to allow specific applications to bypass restrictions that System Integrity Protection would typically apply to them. This allows applications that are part of macOS to provide system functionality, such as app installation and software updates, that would otherwise be prohibited by System Integrity Protection.
(with user-approval …)
One aspect of TCC that most existing analyses of it miss is that the Platform Sandbox Policy also backstops TCC. The sandbox kernel extension supports triggering TCC prompts when a program accesses specific resources, rather than being limited to merely allowing or denying the access, and the platform sandbox policy makes use of this facility
Specifically, allow
actions in the platform sandbox policy can have a (with user-approval "<type>")
modifier attached to them. This triggers an up-call
from the Sandbox kernel extension to the sandboxd
user-space helper asking for
TCC approval of the specified type. sandboxd
translates this into a call to
tccd
, much like a system framework using TCCAccessRequest
to verify
that the calling application is permitted to access a given resource.
A "simple" example
Access to the computer's camera is gated behind the kTCCServiceCamera
TCC
policy. Frameworks that provide access to the camera, such as AVFoundation,
explicitly call TCCAccessRequest(kTCCServiceCamera, …)
to ensure that the
application is permitted to access the camera. But as the camera is a hardware
device, a sufficiently motivated application could access it directly via the
IOKit framework. To safeguard against this, the Platform Sandbox Profile has a
policy in place for iokit-open-user-client
operations that will trigger a TCC
prompt if a camera device is accessed directly via IOKit:
This triggers a kTCCServiceCamera
prompt for any access to
IOFireWireAVCUserClient
, IOUSBInterfaceUserClientV2
with class
kUSBVideoInterfaceClass
, and AppleCamInUserClient
. Platform binaries and
binaries with certain entitlements or identifiers are excluded from the
prompting.
Storage classes
One of the key attributes used within the Platform Sandbox Policy is the concept of the storage class of a file system object. This is a way of classifying a given file system object as containing some type of data that may need special attention.
File system objects are tracked in the sandbox kernel extension as kernel
vnode
objects. A given vnode
is assigned to exactly one storage class at a
time, though the storage class it is assigned to can change. The sandbox kernel
extension caches the mapping from vnode
objects to storage class to avoid
recomputing them. The cache is invalidated in response to certain events
that could cause the mapping to change.
Storage classes are assigned by the Platform Sandbox Policy. The special
storage-class-map
sandbox operation is used along with the (with assign-storage-class "<class>")
action modifier to determine which storage
class should be assigned to a given file system object. Within this portion of
the policy, the same filter operations that are applicable to file system
operations are available, along with predicates involving process or system
attributes.
There are around 130 storage classes defined by the Platform Sandbox Policy as
of macOS 15.1. Most of the storage classes describe data as belonging to a
specific application or framework (CloudKit
, FaceTime
, Safari
, and many
others), while a handful correspond directly to TCC policies (for instance,
kTCCServiceAddressBook
, kTCCServiceSystemPolicyAppBundles
,
kTCCServiceSsytemPolicySysAdminFiles
). You can see the complete list of storage classes
here.
TCC prompting based on storage classes
Much like the iokit-open-user-client
/ kTCCServiceCamera
case presented above, file system
operations consider a combination of path, storage class, and process attributes to determine
whether an operation should result in a TCC prompt.
A sampling of storage classes
kTCCServiceSystemPolicyNetworkVolumes
kTCCServiceSystemPolicyAppBundles
kTCCServiceSystemPolicyDownloadsFolder
kTCCServiceSystemPolicySysAdminFiles
Safari