Skip to content
macOSHow-To July 11, 2026 4 min readViews unavailable

Managing App Privacy Permissions with tccutil and the TCC Database

Resetting stuck permission prompts, understanding why an app sometimes doesn't re-ask for a permission it should, and what the TCC database actually is under the hood.

Every time macOS asks whether an app can access your camera, microphone, contacts, or full disk access, that decision is being recorded by TCC (Transparency, Consent, and Control) — the subsystem tracking privacy permission grants across the system — and tccutil is the command-line tool for directly managing those recorded decisions when the GUI’s Privacy & Security settings pane isn’t sufficient.

Where these permissions actually live

TCC decisions are stored in a SQLite database, separately for system-wide grants and per-user grants:

/Library/Application Support/com.apple.TCC/TCC.db
/Users/<username>/Library/Application Support/com.apple.TCC/TCC.db

Direct modification of these database files is blocked by System Integrity Protection even with root access, which is precisely why tccutil exists as the sanctioned interface for resetting permissions — it’s not just a convenience wrapper, it’s genuinely the only supported way to reset TCC state without disabling SIP entirely, which is not something to do casually.

Resetting a specific permission category for an app

tccutil reset Camera com.example.someapp

This clears the recorded Camera permission decision for the specified app’s bundle identifier specifically, causing macOS to re-prompt for that permission the next time the app actually requests camera access, rather than continuing to enforce whatever decision (allow or deny) was previously recorded.

Resetting an entire permission category system-wide

tccutil reset Microphone

Omitting the bundle identifier resets the specified permission category for every application on the system, which is a considerably broader action — every app that previously had microphone access granted will need to re-request and be re-granted it. This is worth doing deliberately, generally as a troubleshooting step for a specific category-wide problem, rather than as a routine action, given how broadly it resets existing grants.

Finding an app’s exact bundle identifier

tccutil requires the precise bundle identifier, not the application’s display name:

osascript -e 'id of app "Some App Name"'

or, for an already-installed app bundle:

defaults read /Applications/SomeApp.app/Contents/Info.plist CFBundleIdentifier

Getting this wrong (a typo, or using the display name directly) means the reset silently does nothing, since it won’t match any actual recorded TCC entry — worth double-checking directly rather than assuming the display name will work.

Why an app sometimes doesn’t ask for a permission you expect it to

A common point of confusion: an app that should logically need to ask for a permission (say, Full Disk Access) sometimes simply doesn’t prompt, silently failing or behaving as though access were denied without ever showing a request dialog. This frequently traces back to the app never actually triggering the specific system API call that causes TCC to generate a prompt in the first place — TCC prompts are triggered by the specific API call requesting protected data, not proactively by the operating system anticipating what an app might need, so an app using a code path that doesn’t hit that specific trigger simply never prompts, regardless of whether it actually needs the access to function correctly.

Manually granting Full Disk Access when an app doesn’t prompt correctly

For the specific, common case of an app that needs Full Disk Access but doesn’t reliably trigger the automatic prompt, manually adding it through the GUI is the practical workaround:

System Settings > Privacy & Security > Full Disk Access > add the app manually via the "+" button

This is a case where the GUI is actually the more reliable path than tccutil, since Full Disk Access specifically isn’t something tccutil reset can grant — it only resets existing decisions back to an unprompted state, it can’t force a new grant on an app’s behalf.

Listing all current permission grants for review

There’s no single built-in command that cleanly lists every current TCC grant in a readable format, but querying the database directly (read-only, without modifying it) gives visibility SIP’s write-protection doesn’t block:

sqlite3 "$HOME/Library/Application Support/com.apple.TCC/TCC.db" \
  "SELECT service, client, auth_value FROM access;"

This read-only query is useful specifically for auditing exactly what’s currently been granted across every app, without needing to click through each category individually in System Settings’ Privacy pane to build the same picture manually.

Why this system exists as a separate layer from file permissions

TCC’s protections are deliberately independent from standard Unix file permissions — a process running as your own user account, with full standard filesystem read/write permission to your Documents folder, still can’t access Contacts, Camera, or other TCC-protected resources without a separate, explicit TCC grant. This extra layer exists specifically because standard Unix permissions were never designed with this specific privacy threat model in mind — protecting categories of genuinely sensitive personal data from being silently accessed by any process the user happens to be running, regardless of what that process’s baseline file-level permissions already allow.