System
Keychain Metadata
Overview
The macOS Keychain is the system credential manager, storing passwords, certificates, encryption keys, and secure notes. Modern macOS systems use SQLite-based keychain databases that contain both encrypted secret material and unencrypted metadata about each stored item.
Forensic analysis of keychain metadata (without decrypting secrets) provides substantial investigative value: it reveals what services a user has credentials for, which servers and accounts they access, when credentials were created or modified, and how security is configured through Data Protection classes.
macfor extracts only metadata from keychain databases. It never reads, exports, or decrypts the data column containing actual passwords, private keys, or other secret material. This approach provides forensic value while maintaining responsible handling of sensitive data.
Forensic Significance
| Evidence Type | Forensic Value |
|---|---|
| Service names and accounts | Maps the user's credential landscape -- email, VPN, Wi-Fi, web services |
| Server hostnames and protocols | Network services accessed, including internal corporate systems |
| Creation/modification timestamps | Timeline of when accounts were established or passwords changed |
| iCloud sync status | Whether credentials are synced across devices |
| Tombstone markers | Soft-deleted credentials that may still exist in the database |
| Certificate metadata | Identity certificates, code signing, enterprise trust relationships |
| Key capabilities | Cryptographic key usage (signing, encryption, Secure Enclave backing) |
| Protection classes | Security posture -- when credentials are accessible (device locked vs. unlocked) |
Important Note on Secret Values
macfor deliberately excludes the data column from all keychain queries. This column contains the actual encrypted password, key material, or certificate data. The tool extracts labels, account names, service identifiers, timestamps, and configuration metadata only.
File Locations
Per-User Keychains
| Keychain | Path | Format | Description |
|---|---|---|---|
| Data Protection keychain | ~/Library/Keychains/{UUID}/keychain-2.db | SQLite + WAL | Primary modern keychain (macOS 10.12+) |
| Login keychain | ~/Library/Keychains/login.keychain-db | SQLite | Traditional login keychain |
| iCloud status | ~/Library/Keychains/accountStatus.plist | Binary plist | iCloud Keychain enablement state |
The {UUID} directory under ~/Library/Keychains/ is a UUID-named subdirectory that contains the Data Protection keychain. Multiple UUID directories may exist; each should be enumerated and collected.
System Keychain
| Keychain | Path | Format | Requires |
|---|---|---|---|
| System keychain | /Library/Keychains/System.keychain | SQLite | Root access |
The System keychain stores Wi-Fi passwords, VPN credentials, and certificates used by system-level services.
Database Schema
All keychain SQLite databases share the same core table structure.
Tables
| Table | Contents | Key Evidence |
|---|---|---|
genp | Generic passwords | Application passwords, Wi-Fi, VPN, authentication tokens |
inet | Internet passwords | Web credentials with server, protocol, port, path |
cert | Certificates | X.509 certificates with subject, issuer, serial number |
keys | Cryptographic keys | Key metadata with class, size, capabilities |
tversion | Schema version | Database version tracking |
Generic Passwords (genp table)
| Column | Field Name | Type | Description |
|---|---|---|---|
rowid | rowid | int | Row identifier |
cdat | created | time | Creation timestamp (Core Data) |
mdat | modified | time | Modification timestamp |
labl | label | BLOB/string | User-visible display name |
acct | account | BLOB/string | Account name / username |
svce | service | BLOB/string | Service name (e.g., "AirPort", app bundle ID) |
agrp | access_group | BLOB/string | Application entitlement group |
pdmn | protection_domain | string | Data Protection class code |
desc | description | BLOB/string | Item description |
icmt | comment | BLOB/string | User comment |
crtr | creator | int | Creator application code |
type | item_type | int | Item type code |
invi | invisible | bool | Hidden from Keychain Access UI |
sync | sync | bool | iCloud Keychain sync enabled |
tomb | tombstone | bool | Soft-deleted marker |
UUID | uuid | string | Unique identifier |
The data column (containing the actual password) is never extracted.
Internet Passwords (inet table)
Extends generic passwords with network-specific columns:
| Column | Field Name | Type | Description |
|---|---|---|---|
srvr | server | BLOB/string | Server hostname |
sdmn | security_domain | BLOB/string | HTTP authentication realm |
ptcl | protocol / protocol_raw | string/int | Protocol identifier (see Protocol Mapping) |
port | port | int | Port number |
path | path | BLOB/string | URL path component |
atyp | auth_type | BLOB/string | Authentication type |
Certificates (cert table)
| Column | Field Name | Type | Description |
|---|---|---|---|
ctyp | cert_type | int | Certificate type code |
cenc | cert_encoding | int | Certificate encoding format |
subj | subject_hash | BLOB | DER-encoded subject (base64 in output) |
issr | issuer_hash | BLOB | DER-encoded issuer (base64 in output) |
slnr | serial_number | BLOB | Serial number (base64 in output) |
skid | subject_key_id | BLOB | Subject key identifier |
pkhh | public_key_hash | BLOB | Public key hash |
Keys (keys table)
| Column | Field Name | Type | Description |
|---|---|---|---|
kcls | key_class / key_class_raw | string/int | Key class (public=0, private=1, symmetric=2) |
type | key_type | int | Key algorithm type |
bsiz | key_size_bits | int | Key size in bits |
esiz | effective_size_bits | int | Effective key size |
sdat | start_date | time | Validity start date |
edat | end_date | time | Validity end date |
sens | sensitive | bool | Sensitive flag |
extr | extractable | bool | Whether key can be exported |
encr | can_encrypt | bool | Encrypt capability |
decr | can_decrypt | bool | Decrypt capability |
sign | can_sign | bool | Sign capability |
vrfy | can_verify | bool | Verify capability |
wrap | can_wrap | bool | Wrap (key encryption) capability |
unwp | can_unwrap | bool | Unwrap capability |
tkid | token_id | string | Secure Enclave key reference (e.g., com.apple.setoken) |
Key Fields for Analysis
BLOB Decoding
Many metadata columns in keychain-2.db are stored as BLOBs containing UTF-8 strings rather than as TEXT values. The decoding strategy is:
- Read column as raw bytes.
- If
utf8.Valid(), convert directly to string. - If not valid UTF-8, encode as base64 for safe representation.
Columns requiring BLOB decoding include: labl, acct, svce, srvr, desc, icmt, sdmn, path, alis, atyp, gena, subj, issr, slnr, skid, pkhh, klbl, atag.
Protocol Mapping
The ptcl column in the inet table stores protocol identifiers as big-endian 4-byte ASCII codes packed into an integer:
| Value | ASCII | Protocol |
|---|---|---|
0x66747020 | ftp | FTP |
0x68747470 | http | HTTP |
0x68747073 | htps | HTTPS |
0x696D6170 | imap | IMAP |
0x736D7470 | smtp | SMTP |
0x706F7033 | pop3 | POP3 |
0x6C646170 | ldap | LDAP |
0x73736820 | ssh | SSH |
Unknown protocol codes are represented as hex-formatted strings (e.g., 0x12345678).
Protection Domain Mapping
The pdmn column uses two- or three-letter codes indicating when the item is accessible:
| Code | Constant | Human-Readable | When Accessible |
|---|---|---|---|
ak | kSecAttrAccessibleWhenUnlocked | WhenUnlocked | Only when device is unlocked |
ck | kSecAttrAccessibleAfterFirstUnlock | AfterFirstUnlock | After first unlock until restart |
dk | kSecAttrAccessibleAlways (deprecated) | Always | Always accessible |
aku | kSecAttrAccessibleWhenUnlockedThisDeviceOnly | WhenUnlockedThisDeviceOnly | When unlocked, no sync |
cku | kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly | AfterFirstUnlockThisDeviceOnly | After first unlock, no sync |
dku | kSecAttrAccessibleAlwaysThisDeviceOnly (deprecated) | AlwaysThisDeviceOnly | Always, no sync |
Items with ThisDeviceOnly variants are excluded from iCloud Keychain synchronisation.
Key Class Mapping
| Value | Class | Description |
|---|---|---|
| 0 | public | Public key (can be freely shared) |
| 1 | private | Private key (should never leave the device) |
| 2 | symmetric | Symmetric encryption key |
Timestamps
Keychain timestamps (cdat, mdat, sdat, edat) use Core Data timestamps: seconds since 2001-01-01 00:00:00 UTC.
To convert to Unix epoch:
unix_timestamp = core_data_timestamp + 978307200
Where 978307200 is the number of seconds between 1970-01-01 and 2001-01-01.
Analysis Notes
Credential Landscape Mapping
Generic passwords reveal the applications and services a user has stored credentials for. Common patterns:
| Service Pattern | Indicates |
|---|---|
AirPort | Wi-Fi network credentials |
com.apple.* | Apple system services |
Bundle IDs (e.g., com.example.app) | Third-party application credentials |
Chrome Safe Storage | Chrome browser encryption key |
application-password:* | Application-specific passwords (e.g., Google app passwords) |
Internet passwords provide a detailed view of web service access:
| Pattern | Indicates |
|---|---|
| Corporate domains | Enterprise system access |
| VPN endpoints | Remote access infrastructure |
| Mail servers (IMAP/SMTP) | Email account configuration |
| SSH servers | Remote shell access history |
Tombstone Analysis
Soft-deleted items (tomb = 1) remain in the database until they are purged. These represent credentials that the user explicitly deleted but whose metadata persists. The presence of tombstoned credentials for specific services can indicate:
- Credential rotation (old password deleted, new one created)
- Account closure
- Deliberate cleanup of credential evidence
iCloud Keychain Sync
The sync column indicates whether an item is synchronised via iCloud Keychain. Items with sync = 1 exist on all of the user's Apple devices. This is relevant when:
- Establishing that credentials were accessible from multiple devices
- Identifying items that are device-specific (
ThisDeviceOnlyprotection class) - Understanding the scope of a potential credential compromise
The accountStatus.plist file contains a simple boolean indicating whether iCloud Keychain is enabled for the user account.
Secure Enclave Keys
Keys with a tkid (token ID) value of com.apple.setoken are backed by the Secure Enclave. These keys cannot be exported from the device and include:
- Passkey credentials (FIDO2/WebAuthn)
- Touch ID / Face ID authentication keys
- Apple Pay keys
- Device attestation keys
Permission Requirements
- User keychains require the file owner's permissions or root access.
- System.keychain requires root access.
- WAL and SHM files should be collected alongside the main database for transaction recovery.
- On a live system, the keychain database may be locked by
securityd.
Version Differences
| macOS Version | Differences |
|---|---|
| 10.15 (Catalina) | Baseline. APFS volume split, keychains on Data volume. |
| 11 (Big Sur) | Data Protection keychain syncs all content with iCloud Keychain. |
| 12 (Monterey) | Passkey support added. sysb column added to tables. |
| 13 (Ventura) | pcss, pcsk, pcsi, persistref columns added. |
| 14 (Sonoma) | clip, ggrp columns added. |
| 15 (Sequoia) | Standalone Passwords app introduced. No schema changes. |
The collector handles missing columns gracefully -- newer columns are optional in queries and their absence does not cause errors.
Legacy Keychain Format
Pre-Sierra macOS used a binary .keychain format (not SQLite). These legacy files are out of scope for macfor. If encountered, tools like chainbreaker can parse the legacy binary format.
Tool Support
| Tool | Support |
|---|---|
| macfor | Full metadata extraction from genp, inet, cert, keys tables; BLOB decoding; protocol/protection mapping; iCloud status |
| Keychain Access (macOS built-in) | GUI keychain viewer (requires user password to view secrets) |
| security (macOS built-in) | Command-line keychain operations |
| chainbreaker | Legacy binary keychain parser and decryptor |
| DB Browser for SQLite | Manual database inspection |
| AXIOM (Magnet) | Commercial keychain analysis |
| Elcomsoft Phone Breaker | Commercial keychain decryption |
References
- Keychain Data Protection - Apple Platform Security Guide
- Apple Open Source - SecItemDb.c
- A Deep Dive into Apple Keychain Decryption - Forensic Focus
- MacOS Keychain Database File Format (libyal/dtformats)
- macOS Keychain - HackTricks
- chainbreaker - Keychain Forensic Tool
- An Introduction to Keychains (Eclectic Light)