IMPORTANT: The information outlined below might give you just enough rope to hang yourself. I take no responsibility for the accuracy of the information in this post, or for any damage you cause while relying on it.
TCC (Transparency, Constent, and Control) is how macOS manages the permissions requested by apps and granted by users to things like the microphone, location, application control, and more.
I just spent the last couple hours trying to clean up the mess left behind while working on one of my current macOS app projects. Because the app installs a CGEventTap, it requires “Accessibility” permission from the user (System Settings -> Privacy & Security -> Accessibility). In order to test new user flows, I needed to be able to reset those settings. Compounding the problem, I had changed the name of the app a few times, and had several, even duplicate, entries for it.
To be clear, these are problems caused by Apple’s poor design, implementation, and documentation of TCC.
macOS stores TCC user consent in a few places on disk:
/Library/Application Support/com.apple.TCC/
/Users/*/Library/Application Support/com.apple.TCC/
- Perhaps others, but not on my machine (macOS 14.2)
Inside those directories is TCC.db
, a SQLite database, and a directory AdhocSignatureCache
.
This directory contains a number of “Mac OS X Detached Code Signature” files with UUID
strings for names, and a file named keys
.
Using tccutil
Generally, you delete entries using tccutil
:
% sudo tccutil reset All com.exmaple.AppBundleID
Password:
Successfully reset All approval status for com.exmaple.AppBundleID
Successfully reset All approval status for com.exmaple.AppBundleID
Successfully reset All approval status for com.exmaple.AppBundleID
It always seems to print three lines, even if I repeat the command.
In this example, “All” refers to all services to which the app may have been granted permission.
Unfortunately, if the app bundle itself no longer exists on the disk, you’ll get an error:
% sudo tccutil reset All com.exmaple.MissingAppBundleID
Password:
tccutil: No such bundle identifier "com.exmaple.MissingAppBundleID": The operation couldn’t be completed. (OSStatus error -10814.)
And the entry will remain in the TCC.db
file (and System Settings will show an entry for the app).
Using SQLite
The TCC registry is a SQLite DB. You can modify this DB directly, but you must first disable System Integrity Protection (SIP).1
Once you’ve done that, you can list entries for an app like this:
% sudo sqlite3 /Library/Application\ Support/com.apple.TCC/TCC.db
sqlite> select * from access where client like '%Daisy%';
service client client_type auth_value auth_reason auth_version csreq policy_id indirect_object_identifier_type indirect_object_identifier indirect_object_code_identity flags last_modified pid pid_version boot_uuid last_reminded
------------------------------- ------------------------------------ ----------- ---------- ----------- ------------ ----- --------- ------------------------------- -------------------------- ----------------------------- ----- ------------- --- ----------- --------- -------------
kTCCServiceSystemPolicyAllFiles com.daisydiskapp.DaisyDiskStandAlone 0 0 5 1 ?? UNUSED 0 1641727294 UNUSED 0
This shows that DaisyDisk has been granted “Full Disk Access” permission. To remove it, do this:
sqlite> delete from access where client = 'com.daisydiskapp.DaisyDiskStandAlone';
sqlite> ^D
Once you’ve removed the stale entries, don’t forget to re-enable SIP!
When You Can’t Find the Entry
If you can’t find the entry for your app, but it’s still showing up in System Settings, be
aware that sometimes macOS writes the client
value as a path to the application binary.
In my case, it was like this:
sqlite> select * from access where client like '%ReKey%';
service client client_type auth_value auth_reason auth_version csreq policy_id indirect_object_identifier_type indirect_object_identifier indirect_object_code_identity flags last_modified pid pid_version boot_uuid last_reminded
------------------------ ------------------------------------------------------------ ----------- ---------- ----------- ------------ ----- --------- ------------------------------- -------------------------- ----------------------------- ----- ------------- --- ----------- --------- -------------
kTCCServicePostEvent /Users/me/Library/Developer/Xcode/DerivedData/ReKey-dmirb 1 2 4 2 ?? 0 UNUSED 0 1696485626 UNUSED 0
tqbnbsehigusolzjwvezofn/Build/Products/Debug/ReKeyAgent
kTCCServicePostEvent /Users/me/Library/Developer/Xcode/DerivedData/ReKey-dmirb 1 2 4 2 ?? 0 UNUSED 0 1696489748 UNUSED 0
tqbnbsehigusolzjwvezofn/Build/Products/Debug/ReKey.app/Conte
nts/Resources/ReKeyAgent
kTCCServicePostEvent /Users/me/Library/Developer/Xcode/DerivedData/ReKey-dmirb 1 2 4 2 ?? 0 UNUSED 0 1697670395 UNUSED 0
tqbnbsehigusolzjwvezofn/Build/Products/Debug/ReKey Helper
kTCCServicePostEvent /Users/me/Library/Developer/Xcode/DerivedData/ReKey-dmirb 1 2 4 2 ?? 0 UNUSED 0 1698656027 UNUSED 0
tqbnbsehigusolzjwvezofn/Build/Products/Debug/ReKey.app/Conte
nts/Resources/ReKey Helper
kTCCServiceAccessibility /Users/me/Library/Developer/Xcode/DerivedData/ReKey-dmirb 1 2 4 1 ?? 0 UNUSED 0 1698656027 UNUSED 0
tqbnbsehigusolzjwvezofn/Build/Products/Debug/ReKey.app/Conte
nts/Resources/ReKey Helper
And this was the source of the double duplicate entries I was seeing.
The Other Files
The steps above are probably sufficient to clean up TCC and System Settings. But if you’re
still seeing evidence of the apps, consider removing the appropriate AdhocSignatureCache
files.
I found the right ones by using The Silver Searcher (installed via brew):
% cd /Library/Application\ Support/com.apple.TCC/
% ag -o --search-binary ReKey
Binary file AFC61784-3BE7-4FD5-93EE-48F4AC98B24E matches.
Binary file D69EDEE2-AF52-4286-831D-F3B130689394 matches.
Binary file F81364ED-F9A6-4B84-B0DC-37C464FB89AE matches.
The keys
file is a Plist (NSKeyedArchiver
serialization). It’s probably not wise
to edit this file. Before thinking it through, I deleted some array entries that
were paths to my missing binaries. I haven’t noticed any adverse result from doing this,
but I don’t know enough about NSKeyedArchiver
to know if I screwed up some internal
references or not.
Final Notes
These kinds of edits are not for the feint of heart. I take no responsibility for the accuracy of the information in this post, or for any damage you cause while relying on it.
To make any chances to TCC files, you must disable SIP. Don’t forget to reenable it when you’re done with your edits.
And it’s probably a good idea to make backup copies of the files before you edit or delete them.
If you do somehow screw things up, try using tccutil reset
to reset all permissions.
You’ll have to re-enable them for all your apps as you encounter them, but it should
solve any issues (note, I have not tried this myself).
Resources
I learned all this through experimentation and some information found online:
- https://eclecticlight.co/2023/02/12/last-week-on-my-mac-children-animals-and-tcc/