Modifying the TCC database

Mountain Lion introduced a new iOS-like feature to allow users to be notified when an application requests access to that user’s contacts:

…and to be able to modify this access later:

Why does Final Cut Pro 7 want to access contacts? Final Cut Pro 7 introduced a feature that uses iChat (which doesn’t even really exist in Mountain Lion), therefore when a user first launches FCP, OS X will ask permission to allow FCP to access that user’s contacts.

It might be nice to be able to pre-allow or -disallow access for applications without user intervention, especially in scenarios where user Library data isn’t persistent across logins in a multi-user environment, where users would otherwise be nagged frequently to access what’s likely an empty Contacts database.

These contacts turn out to be stored in an SQLite3 database, located in the user’s library folder:

~/Library/Application Support/

This database is managed by the tccd daemon located at:


We can query it with the built-in sqlite3 command-line tool:

➜ sqlite3 ~/Library/Application\ Support/

SQLite version 3.7.12 2012-04-03 19:43:07
Enter ".help" for instructions
Enter SQL statements terminated with a ";"

sqlite> .tables
access access_overrides access_times admin

There’s some useful information in the access table:

sqlite> .dump access
PRAGMA foreign_keys=OFF;
CREATE TABLE access (service TEXT NOT NULL, client TEXT NOT NULL, client_type INTEGER NOT NULL, allowed INTEGER NOT NULL, prompt_count INTEGER NOT NULL, CONSTRAINT KEY PRIMARY KEY (service, client, client_type));
INSERT INTO "access" VALUES('kTCCServiceAddressBook','',0,1,0);
INSERT INTO "access" VALUES('kTCCServiceAddressBook','',0,1,0);

Here we’ve got FCP and Google Chrome (the latter triggered because we visited GMail). The last three integer columns store the values for client_type, allowed, and prompt_count.

Given this very simple database schema, it’s pretty trivial to update this database ourselves directly. In my experience, when the database gets updated, the Security & Privacy preferences pane responds to the change as soon as its window again receives focus.

I wrote a Python script that allows for ad-hoc changes to the allowed column, given an app bundle id. It should also be usable in scenarios where a user may be brand new and not yet had the TCC database created, so it will handle the initial schema creation of the database if it doesn’t already exist. This is available here. It currently assumes you’ll be running the script as the user whose database will be modified.

However, since I originally wrote this script for a very simple purpose on 10.8, Pierce Darragh and Richard Glaser of the University of Utah Marriott Library have taken these ideas and run with them with the Privacy Services Manager tool, and much further expanded the scope of services upon which it can operate, supporting new-since-10.8 OS X features and changes to the underlying mechanisms that control their behaviour. While I haven’t used this tool, it looks like they have put a lot of work into it, so I’d recommend looking into this if managing these controls is of interest to you.

Tagged , , , , , , . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.


  1. Oliver
    Posted November 26, 2012 at 9:48 am | Permalink

    Excellent article. I look forward to giving this a try!

  2. bsdjunkie
    Posted May 13, 2013 at 11:17 am | Permalink

    Any link to the sample plist file?

  3. Allister
    Posted May 31, 2013 at 12:47 am | Permalink

    Thanks for your work, the tool, and the writeup! Just to be super-explicit re: usage steps, this would be activated by a launchagent/loginItem to cover any new users, with something like a dotfile whose absence would trigger tccmanager for the Apps we know we want to suppress this for?

    • Posted May 31, 2013 at 1:06 pm | Permalink

      Yes, using a LaunchAgent login script is one way to have this run as the user whose TCC DB you want to update. I use a version of Nate Walck’s scriptRunner to do this, which also conveniently has a built-in mechanism to run something “once” if you want. However, you should be able to pass “–allow ” repeatedly and it will just overwrite the existing data it has for that app bundle.

  4. Mike
    Posted October 27, 2013 at 2:44 pm | Permalink

    Thanks for the post! Modifying your work here, I’ve been able to automate Terminal accessibility access in Mavericks for use in bash provisioning routines that include AppleScript snippets.

    sudo sqlite3 /Library/Application\ Support/ “INSERT or REPLACE INTO access values (‘kTCCServiceAccessibility’, ‘’, 0, 1, 0, NULL);”

  5. Klaus
    Posted November 18, 2013 at 6:49 pm | Permalink

    Great information!
    I’ve read that on another site already, but it doesn’t work for me.
    The quotes are messed up but changing them produced an error at INSERT or REPLACE, wrong options.

    I would like to add an Internet Account for a shared Calendar. Would be cool if I could automate it.
    Is that possible?

  6. Thomas
    Posted December 16, 2013 at 10:51 am | Permalink

    Looks like in Mac10.9 they added a new column to the TCC.db, maybe an update here is needed?

    • Posted December 16, 2013 at 10:54 am | Permalink

      Correct. I haven’t yet had time to do an update.

  7. Posted February 11, 2014 at 7:27 pm | Permalink


    There are three valid service names: “kTCCServiceAddressBook” (Contacts), “kTCCServiceAccessibility” (Accessibility), and “kTCCServiceUbiquity” (iCloud). And two locations for the tcc.db, one for current user and the other for host.

    ~/Library/Application Support/
    /Library/Application Support/

    The “kTCCServiceAccessibility” (Accessibility) service used the /Library TCC.db

    • Posted February 13, 2014 at 5:55 pm | Permalink

      FYI, we have a python script in github that works with the three services in github:

      If anybody is interested in checking it out.

      • Posted March 26, 2014 at 9:48 am | Permalink

        Thanks Richard. I’ve finally updated the original post with a link to yours, since you guys have clearly done more work than I have keeping this up to date.

        • Pierce Darragh
          Posted June 26, 2014 at 7:29 pm | Permalink

          Hi Tim,

          I’ve been the main developer for the script Richard has been referencing, and I’ve stopped supporting it and have moved to a more-complete script that can also handle Location Services requests.

          In short, Location Services is handled in an entirely different manner, so I originally had chosen not to combine it with the tcc_database_manager. Recently I decided to merge them after all, and I’ve since put more work into a more unified privacy_services_manager, available here:

          Would you mind updating the link in this post to point to this page instead? I’ve got redirects on the original in the meantime.

          Thanks again for posting this in the first place!

          • Posted June 30, 2014 at 12:39 pm | Permalink

            Hi Pierce, I’ve just updated the original post. Thanks!

  8. TGB
    Posted May 26, 2014 at 3:26 am | Permalink

    The work you guys have all done on this is awesome, and I ended up using tcc_database_manager to solve my problem much more simply an elegantly than trying to figure out sqlite3. My only feedback with that tool is that it doesn’t gracefully handle attempts to reference the (non-existent) Accessibility table when run on 10.8.

    All this really means is having to wrap it as:
    if [ `sw_vers -productVersion | awk -F. '{ print $2 }'` -eq 9 ]; then /sbin/tcc_database_manager add accessibility; fi

    It would be nice if tcc_database_manager handled it a little more cleanly than:

    Traceback (most recent call last):
    File “/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/”, line 162, in _run_module_as_main
    File “/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/”, line 72, in _run_code
    File “/sbin/tcc_database_manager/”, line 85, in
    File “/sbin/tcc_database_manager/”, line 59, in main
    File “/sbin/tcc_database_manager/”, line 36, in __init__
    sqlite3.OperationalError: unable to open database file

    But otherwise, great work, very grateful.

    • Posted May 26, 2014 at 9:30 am | Permalink

      Thanks for opening an issue on their repo for this!

    • Posted May 27, 2014 at 2:33 pm | Permalink

      Hello TGB:

      Sorry, about the issue we will do some tests and get back to you once we have replicated the bug.

      Does this happen with any version of OS X 10.8 or other computers running OS X 10.8? Just making sure its not an issue with a specific machine vs a global OS X 10.8 issue.

    • Posted May 28, 2014 at 5:47 pm | Permalink

      We think we’ve got this fixed, as of 9f987b8.

      @TGBX, the issue wasn’t quite what you had thought. The way the script was written previously, it should have just written ‘accessibility’ values to the database regardless of whether or not they would be used without checking. The actual issue was that the root-level TCC database at /Library/Application Support/ did not exist, and my checks to create the file were not done correctly. The new version (3.2) accommodates for this.

      However, seeing as checking for OS version is useful anyway, we went ahead and included that as part of the update. The script now checks for OS compatibility using the method pointed to by @timsutton (thanks, Tim!).

      I hope this works better for you now! Thanks for liking it and using it!

      To get the latest version of the tcc_database_manager, see the GitHub repo:

      If you have any other feature requests or bugs please let us know.

      • Posted June 27, 2014 at 2:36 pm | Permalink


        We have made a management utility to administrate OS X Location Services, Contacts requests, Accessibility, and iCloud access in enterprise environments.

        It runs on OS X 10.8 & 10.9 and has been tested with OS X 10.10 “Yosemite”.

        Since Mac OS X 10.8 “Mountain Lion”, Apple has introduced systems to handle access to certain features of the computer. Among these are Contacts (AddressBook), iCloud (Ubiquity), Accessibility, and Location Services. The first three are managed through one method (SQLite databases called TCC.db hidden throughout the system), while the latter is handled by the locationd daemon through property list files. Originally I created two separate scripts to accommodate the manual modification of these systems. However, eventually I realized that while the internal workings were different, the desired effect was more or less the same. This Privacy Services Manager is a compilation (and mild reformation) of those two scripts.

        The script is fairly straightforward, though there are some options:

        $ [-hvn] [-l log] [-u user] [--template] [--language] action service applications


        Option Purpose
        -h, –help Prints help information.
        -v, –version Prints version information.
        -n, –no-log Redirects logging to stdio.
        –template Modify permissions for Apple’s User Template. Only applies to certain services.
        -l log, –log-dest log Redirect logging to the specified file. (This can be overridden by –no-log.)
        -u user, –user user Modify permissions for user, not yourself. (Requires root privileges.)
        –language lang When changing permissions for the User Template, modify the langtemplate.

        Our two other GitHub repos

        - tcc_database_manager
        - location_services_manager

        Are deprecated and replaced by the more-complete & actively developed and supported Privacy Services Manager

        We also have included a package installer/uninstaller for those using package distribution systems or to ease installation for the busy/less technical.

        If you have any questions, problems or features requests feel free to email me off-list or send email or file a issue via the GitHub repo.

        For more information see the following web page:

Leave a Reply