File accessNetworkUser activity
iCloud Drive (CloudDocs): macOS Sync Folders and Databases
iCloud Drive local folders and the CloudDocs client.db and server.db databases that list synced files, versions and the devices that wrote them.
- Location
- ~/Library/Application Support/CloudDocs/session/db/client.db
- Proves
- Which files were in the user's iCloud Drive, when, and from which of their devices
- Timestamps
- Unix epoch seconds (UTC) in CloudDocs databases
- Access
- User or root; Full Disk Access for the collector on a live system
- Retention
- Current sync state; items leave when deleted and purged from iCloud
- Collection
- UAC, mac_apt, Disk image, ditto
Tools
Compare all tools- mac_aptCLI · open source
- sqlite3CLI · built into macOS
What it is
iCloud Drive syncs a user's documents between their Apple devices and Apple's servers. On macOS the synced files live in a hidden folder in the user's Library, and the CloudDocs service (historically the bird daemon) keeps SQLite databases describing every item it knows about: file names, parent folders, sizes, modification times and the device that produced each version.
That makes it useful in data theft and insider cases: a file can appear in the database with a version written by another device on the same Apple Account, or be listed server-side even when it is not downloaded locally. From macOS 14 Sonoma, iCloud Drive runs on Apple's File Provider framework, so fileproviderd and the com.apple.FileProvider log subsystem carry much of the activity that CloudDocs used to log.
Where it lives
| Item | Path | Notes |
|---|---|---|
| iCloud Drive root | ~/Library/Mobile Documents/com~apple~CloudDocs/ | What Finder shows as "iCloud Drive" |
| App containers | ~/Library/Mobile Documents/<container>/ (for example com~apple~Pages) | Per-app iCloud documents |
| CloudDocs databases | ~/Library/Application Support/CloudDocs/session/db/client.db and server.db | SQLite; collect -wal and -shm too |
| Account (older macOS) | ~/Library/Preferences/MobileMeAccounts.plist | Apple Account identifiers; can be empty on newer versions |
| Account (newer macOS) | ~/Library/Accounts/Accounts4.sqlite | Account records, including the Apple Account |
| iCloud account files | ~/Library/Application Support/iCloud/Accounts/ | Collected by UAC |
| Logs | Unified Logs: com.apple.clouddocs, com.apple.FileProvider (Sonoma+), com.apple.cloudkit | Sync activity |
Protection: these are user-owned, but on a live system many ~/Library subfolders are TCC-protected, so run the collector with Full Disk Access. Files evicted with "Optimize Mac Storage" are dataless on disk: metadata and inode remain, but content is only in the cloud.
What it proves
- That a named file or folder was in the user's iCloud Drive, with its path, size and modification time.
- Which device wrote the current version of an item (
version_device, resolved through thedevicestable). - That the user had iCloud Drive enabled and which app containers were in use.
- That files existed server-side even if not present locally (
server_items).
It does not prove:
- That a person opened a file. Sync writes rows without user interaction.
- Upload time of a specific transfer. The fields below are item and version times.
- Content of evicted files; those must be obtained from the provider through legal process.
Key fields
Tables and columns as read by mac_apt's ICLOUD plugin:
| Table (database) | Column | Meaning |
|---|---|---|
client_items (client.db) / server_items (server.db) | item_id, item_parent_id | Item and parent identifiers; walk them to build full paths |
item_filename | Name of the file or folder | |
item_type | mac_apt maps 0 to folder and 1 to file | |
item_birthtime | Item creation time | |
item_lastusedtime | Last used time recorded for the item | |
version_mtime | Modification time of the current version | |
version_size | Size of the current version | |
version_name | Name recorded for the version | |
version_device | Key of the device that produced the version | |
item_sharing_options | Non-zero when the item is shared | |
devices (server.db) | key, name | Device key and human-readable device name |
app_libraries (client.db) | app_library_name | App container the item belongs to (joined via app_library_rowid) |
Timestamps
The time columns above are Unix epoch seconds in UTC:
SELECT item_filename,
datetime(item_birthtime, 'unixepoch') AS birth_utc,
datetime(item_lastusedtime, 'unixepoch') AS lastused_utc,
datetime(version_mtime, 'unixepoch') AS version_mtime_utc,
version_size, version_device
FROM server_items
ORDER BY version_mtime DESC
LIMIT 50;
Files in Mobile Documents carry normal APFS timestamps (nanoseconds since 1970, UTC).
Retention
The databases reflect current sync state: rows follow items as they are added, changed and deleted, and there is no documented local history table. Turning iCloud Drive off or signing out changes local state, so collect before any account change. Look in FSEvents, backups and snapshots for older states.
Collection
# Live, terminal with Full Disk Access, as the user or root
ditto ~/Library/Application\ Support/CloudDocs/session/db /Volumes/CASE/MBP01/CloudDocs_db
ls -laR ~/Library/Mobile\ Documents > /Volumes/CASE/MBP01/mobile_documents_listing.txt
log show --info --predicate 'subsystem == "com.apple.FileProvider" OR subsystem == "com.apple.clouddocs"' --last 3d > /Volumes/CASE/MBP01/icloud_logs.txt
- UAC
fullprofile (files/applications/icloud.yaml) collectsclient.db*andserver.db*plus~/Library/Application Support/iCloud/Accounts. - mac_apt
ICLOUDreads the databases from an image. - Copying the whole
Mobile Documentstree on a live Mac can trigger downloads of evicted files and change state. List it first; decide on content collection separately. brctl dumpprints the CloudDocs state andbrctl diagnosebuilds a diagnostic archive on a live system. Avoidbrctl downloadandbrctl evict, which change the evidence.
Parsing
mac_apt ICLOUD rebuilds full paths with a recursive query and joins the device name:
python3 mac_apt.py -o /cases/MBP01/mac_apt E01 /cases/MBP01.E01 ICLOUD
python3 mac_apt_artifact_only.py -i "/cases/MBP01/CloudDocs_db" -o /cases/MBP01/out ICLOUD
Output tables: iCloudServerItems and iCloudClientItems, with item_path, times, version_device_name and item_is_shared. For ad hoc work, open a copy of each database in sqlite3 and join server_items.version_device to devices.key.
Investigator tips
- A
version_devicethat is not the examined Mac points to another device on the same account; name it viadevices. - Large numbers of items with close
version_mtimevalues can indicate bulk copying into iCloud Drive. Check FSEvents for the matchingMobile Documentspaths. - Desktop and Documents syncing, when enabled, puts those folders inside iCloud Drive; paths may not look like cloud paths at first glance.
- Check the Spotlight store for metadata on paths under
Mobile Documents, including items that are no longer present. - Recently opened iCloud documents also show up in recent items.
- On Sonoma and later, validate which fields the CloudDocs databases still populate on a test Mac of the same version before relying on absence.