Skip to content

TCC.dbTCC.db-wal

TCC Parser

Who was allowed to read the disk, watch the screen or drive the Mac?

Decode the macOS TCC databases (system and per-user, with their write-ahead logs) into permissions, apps, a timeline and recovered history, with review flags for risky grants. Parsed in your browser with WebAssembly: nothing is uploaded.

Drop TCC.db files, a folder or a collection archive

System and per-user TCC.db with their -wal and -shm, MDMOverrides.plist, or a whole UAC, Velociraptor or Aftermath collection (.zip, .tar.gz). Everything is decoded on your device.

No data at hand? Try a sample: the synthetic Mac FIN-MBP-03 from a fictional intrusion (TCC.db + WAL for the system and one user, plus MDMOverrides.plist).

100% in your browser — Rust + WebAssembly, nothing is uploaded

How to get your data

Full acquisition guide

Each Mac has one system TCC.db and one per user, each with a TCC.db-wal that can hold the latest changes and older versions of rows. Copy the whole com.apple.TCC folders, not just TCC.db, and keep their paths so the tool knows which database is whose.

  1. Copy the com.apple.TCC folders (Full Disk Access needed)
  2. Drop the folder or the archive here
  3. Parsed locally — nothing leaves the browser

On the live Mac, give Terminal Full Disk Access (System Settings › Privacy & Security › Full Disk Access), reopen it and paste this block in an admin account. ditto copies each com.apple.TCC folder as it is, with TCC.db-wal, TCC.db-shm and MDMOverrides.plist, and keeps the Library/… and Users/<name>/… layout.

Terminal · zsh / bash · admin
C=~/Desktop/tcc_case; mkdir -p "$C"
sudo ditto "/Library/Application Support/com.apple.TCC" "$C/Library/Application Support/com.apple.TCC"
for u in /Users/*; do
  d="$u/Library/Application Support/com.apple.TCC"
  [ -d "$d" ] && sudo ditto "$d" "$C/Users/$(basename "$u")/Library/Application Support/com.apple.TCC"
done
R="/private/var/root/Library/Application Support/com.apple.TCC"
sudo test -d "$R" && sudo ditto "$R" "$C$R"
sudo ditto -c -k --keepParent "$C" ~/Desktop/tcc_case.zip

You get ~/Desktop/tcc_case and tcc_case.zip. Drop either one on the page.

Granting Full Disk Access to Terminal writes a row into the system TCC.db itself: note the time you did it so your own grant is not mistaken for the intruder's.

Gotchas

  • Without Full Disk Access for the process doing the copy (Terminal, the agent, the collector), the copy fails with “Operation not permitted” or comes back empty.
  • Take TCC.db-wal with TCC.db. Tools that copy only TCC.db (UAC's tcc.yaml, Aftermath) miss the changes still in the WAL and the history it holds.
  • Every account has its own TCC.db, including root under /private/var/root.
  • Never open the evidence with sqlite3 in read-write mode: closing it checkpoints the WAL into TCC.db and removes the -wal file, erasing the history this tool recovers. Work on copies and hash them first.
  • A copy taken while tccd is writing can be torn; the tool only replays WAL frames with valid checksums and lists the rest in History.

What is TCC.db?

Transparency, Consent and Control (TCC) is the macOS framework that decides whether a program may use the camera, microphone, screen, keyboard events, accessibility APIs, protected folders, Full Disk Access or Apple Events automation. The daemon tccd records every standing decision in SQLite databases named TCC.db: one for the system and one per user.

Each row is a decision for one program (bundle ID or path) and one service, with the decision (allowed, denied, limited), why it was made, the program's code requirement and when the decision last changed. It is a permissions register, not a usage log.

Where it is stored

  • /Library/Application Support/com.apple.TCC/TCC.db: system database (SIP- and TCC-protected), usually Full Disk Access, Accessibility, Screen Recording, Input Monitoring.
  • ~/Library/Application Support/com.apple.TCC/TCC.db for each user: camera, microphone, folders, removable volumes, Automation and more.
  • TCC.db-wal next to each database: the write-ahead log with recent changes and older copies of pages.
  • /Library/Application Support/com.apple.TCC/MDMOverrides.plist: grants pushed by MDM configuration profiles (PPPC).

Why it matters in an investigation

  • Shows which programs could read everything (Full Disk Access), watch the screen, log keystrokes or control the UI, including a terminal or a script host that everything else runs through.
  • Dates the last change of each decision (Unix seconds, UTC): a burst of grants during an intrusion window is a strong pointer.
  • Path-based clients in temporary, shared or hidden folders and ad-hoc signed code requirements point to dropped tools.
  • The WAL and free pages can keep grants that were later removed with tccutil reset.

Limitations

  • A row shows a decision, not its use: TCC.db does not log each camera activation or file read. Per-request evidence lives in the unified log (subsystem com.apple.TCC).
  • last_modified is the last change only; the first grant time is lost when a row is updated.
  • Removed rows survive only until SQLite reuses the space; a missing row does not prove a permission was never granted.
  • auth_reason values and some columns (flags, pid, boot_uuid) are not documented by Apple; the tool shows raw values next to community interpretations.

How to get the files

  • Copy the whole /Library/Application Support/com.apple.TCC folder and each user's ~/Library/Application Support/com.apple.TCC folder, keeping the paths, from a terminal with Full Disk Access (see “How to get your data”).
  • Collect TCC.db-wal with each TCC.db; UAC's tcc.yaml and Aftermath copy TCC.db only.
  • From an image, mount the Data volume read-only and archive the same folders.

FAQ

Are my TCC databases uploaded anywhere?

No. The parser is Rust compiled to WebAssembly and runs in a Web Worker in your browser. There is no upload endpoint; the tables, findings and exports are built locally.

Which macOS versions are supported?

Any layout of the access table: Mojave and Catalina (allowed, prompt_count), Big Sur to Ventura (auth_value, auth_reason, auth_version) and Sonoma and later (pid, pid_version, boot_uuid, last_reminded). Column names are read from each database's own schema, and unknown columns are shown as they are.

Do I need the -wal and -shm files?

Bring the -wal: it can contain the most recent decisions and older versions of rows, and the tool replays it like SQLite does. The -shm file is only an index of the WAL and is not needed.

What does auth_value 2 mean?

Allowed. 0 is denied, 1 unknown and 3 limited. On Mojave and Catalina the table had an allowed column (1 = allowed) instead, which the tool maps to the same decisions.

What is the csreq column?

A compiled code-signing requirement that identifies the program the decision applies to. The tool decodes it to text such as identifier "com.apple.Terminal" and anchor apple, and shows the team ID or the cdhash of ad-hoc signed code.

Can it recover deleted permissions?

Often, for recent changes: rows removed with tccutil reset or System Settings can survive in WAL frames, in the page versions the WAL replaced, and in free pages. They appear in the History tab until SQLite reuses the space.

About the parser

TCC Parser is an independent Rust implementation compiled to WebAssembly. It reads SQLite files itself, from the public file-format and WAL specifications (sqlite.org), so it can replay the -wal file, list what the WAL replaced and carve rows from free pages, which a normal SQLite query does not show. Columns are read from each database's own schema, so Mojave-era, Big Sur-era and Sonoma-and-later layouts are all decoded. Code requirements (csreq) are decoded to Apple's documented requirement language. auth_reason meanings are community-documented, not published by Apple; verify important conclusions on a test Mac of the same version and in the unified logs.

Step by step: load macOS TCC.db files and their WAL into a free in-browser parser, read the findings, review permissions and history, and export.
How the TCC.db access table changed from Mojave to Big Sur and Sonoma: allowed, auth_value, auth_reason, pid and last_reminded, plus the other tables.
How to read the csreq and indirect_object_code_identity blobs in TCC.db: compiled code requirements, anchors, identifiers and cdhash-only ad-hoc clients.