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/com.apple.TCC/TCC.db

This database is managed by the tccd daemon located at:

/System/Library/PrivateFrameworks/TCC.framework/Resources/tccd

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

➜ sqlite3 ~/Library/Application\ Support/com.apple.TCC/TCC.db

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;
BEGIN TRANSACTION;
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','com.apple.FinalCutPro',0,1,0);
INSERT INTO "access" VALUES('kTCCServiceAddressBook','com.google.Chrome',0,1,0);
COMMIT;

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.

Update: Richard Glaser pointed out below that the Marriott Library IT department has worked on and published an updated-for-Mavericks, and generally more complete script based on the one I wrote. Check it out!

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

12 Comments

  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?
    Allister

    • 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/com.apple.TCC/TCC.db “INSERT or REPLACE INTO access values (‘kTCCServiceAccessibility’, ‘com.apple.Terminal’, 0, 1, 0, NULL);”

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

    Great information!
    @mike:
    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

    FYI

    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/com.apple.TCC/TCC.db
    /Library/Application Support/com.apple.TCC/TCC.db

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

Leave a Reply