Overview
macOS Notification Center stores a history of delivered notifications in a SQLite database. Each notification record includes the delivering application, notification title, subtitle, body text, and delivery timestamp. Notifications from messaging apps, email clients, calendar alerts, and system events are all recorded, providing an independent timeline of application activity and user alerts.
Forensic Significance
| Evidence Type | Forensic Value |
|---|
| Notification content | Message previews, email subjects, alert text |
| Delivering application | Which app generated the notification |
| Delivery timestamps | When notifications were shown |
| App activity evidence | Proof an application was running and generating events |
| Message previews | Partial message content even if the full message is deleted |
| Calendar alerts | Meeting reminders correlating with Calendar data |
File Locations
| Artifact | Path | Format |
|---|
| Notification database | ~/Library/Group Containers/group.com.apple.usernoted/db2/db | SQLite |
| Notification preferences | ~/Library/Preferences/com.apple.ncprefs.plist | Plist |
Database Schema
record table
| Column | Type | Description |
|---|
rec_id | INTEGER | Primary key |
app_id | INTEGER | FK to app table |
uuid | BLOB | Notification UUID |
data | BLOB | Binary plist containing notification content |
delivered_date | REAL | Delivery timestamp (Core Data) |
presented | INTEGER | Whether notification was shown to user |
style | INTEGER | Notification style (banner, alert) |
snooze_fire_date | REAL | Snoozed notification fire date |
app table
| Column | Type | Description |
|---|
app_id | INTEGER | Primary key |
identifier | TEXT | Application bundle identifier |
Notification Data BLOB
The data column contains a binary plist with notification content:
| Key | Description |
|---|
titl / title | Notification title |
subt / subtitle | Notification subtitle |
body | Notification body text |
iden | Notification identifier |
cate | Notification category |
thrd | Thread identifier (for grouped notifications) |
Key Fields for Analysis
Basic Notification History
SELECT
a.identifier AS app,
datetime(r.delivered_date + 978307200, 'unixepoch') AS delivered,
r.presented
FROM record r
JOIN app a ON r.app_id = a.app_id
ORDER BY r.delivered_date DESC
LIMIT 50;
The data blob requires binary plist parsing:
import sqlite3
import plistlib
conn = sqlite3.connect('db')
cursor = conn.execute("""
SELECT a.identifier, r.delivered_date, r.data
FROM record r JOIN app a ON r.app_id = a.app_id
ORDER BY r.delivered_date DESC LIMIT 20
""")
for app, ts, data in cursor:
try:
plist = plistlib.loads(data)
title = plist.get('titl', plist.get('title', ''))
body = plist.get('body', '')
print(f"{app}: {title} - {body}")
except:
pass
Timestamps
Notification Center uses Core Data timestamps (seconds since 2001-01-01 00:00:00 UTC).
Analysis Notes
- Message previews: Notifications from Messages, WhatsApp, Slack, and other messaging apps often include message preview text. This content may persist in the notification database even after the original message is deleted.
- Email subject lines: Mail.app notifications include email subjects and sender names, providing an email activity timeline independent of the Envelope Index.
- Notification preferences: The
com.apple.ncprefs.plist file reveals which apps the user has configured for notifications and their alert style, indicating which apps the user actively monitors. - Retention: Notification records are periodically pruned. The retention period varies by macOS version and notification volume.
- Binary plist content: The notification data column requires binary plist parsing. Not all fields are present in every notification.
- App identification: The
identifier field in the app table maps to application bundle IDs, enabling identification of the source application.
Version Differences
| macOS Version | Changes |
|---|
| 10.8+ | Notification Center introduced |
| 10.14 (Mojave) | Enhanced notification grouping |
| 12 (Monterey) | Focus modes affect notification delivery |
| 13 (Ventura) | Database path changes |
| Tool | Support |
|---|
| macfor | Not yet implemented (planned) |
| sqlite3 + Python | Manual database and plist extraction |
| mac_apt | Open-source notification parser |
References