Full Metal Mac FullMetalMac.com
Logging & Diagnostics advanced BSM audit security forensics

Reading BSM Audit Logs on macOS

Understanding Basic Security Module audit logs — enabling auditing, reading with praudit, and tracking security events

Published: Feb 14, 2026 12 min read

What Is BSM?

The Basic Security Module (BSM) is an auditing framework inherited from Sun Microsystems’ Solaris, implemented on macOS through OpenBSM. While the unified logging system captures operational data for debugging and diagnostics, BSM serves a fundamentally different purpose: it provides a tamper-evident, security-grade audit trail of system events.

BSM records are written in a binary format to /var/audit/ and are designed for compliance, forensics, and security monitoring. Unlike unified logs, BSM audit logs are difficult to modify without detection and can capture granular events like individual file opens, process executions, and authentication attempts at the kernel level.

For Mac admins in regulated environments (healthcare, finance, government), BSM auditing is often a compliance requirement. Even outside those contexts, it is an invaluable forensic data source during incident response.

Audit Configuration Files

BSM behavior is controlled by three configuration files in /etc/security/:

/etc/security/audit_control

The primary configuration file that defines what gets audited and how audit files are managed:

# View the current audit configuration
cat /etc/security/audit_control

Key directives:

DirectivePurposeExample
dirDirectory where audit trails are storeddir:/var/audit
flagsDefault audit event classes for all usersflags:lo,aa,ad,pc,fc,fd
minfreeMinimum free disk percentage before warningminfree:5
naflagsEvents audited even when no user is attributednaflags:lo,aa
policyAudit policy flagspolicy:cnt,argv,arge
fileszMaximum audit file size before rotation (0 = unlimited)filesz:2M
expire-afterAuto-purge old audit filesexpire-after:10M

/etc/security/audit_class

Maps two-letter class codes to bitmask values. The default macOS installation includes:

ClassCodeDescription
lo0x00001000Login and logout events
aa0x00000013Authentication and authorization
ad0x00000800Administrative actions
pc0x00000008Process creation and termination
fc0x00000004File creation
fd0x00000020File deletion
fw0x00000002File write / modification
fr0x00000001File read
ex0x40000000Program execution
nt0x00000400Network events

/etc/security/audit_event

Maps numeric event IDs to human-readable names and their class membership. This file contains hundreds of entries covering every auditable system call.

Enabling and Managing Auditing

Check Audit Status

# Check if auditd is running
sudo launchctl list | grep auditd

# View the current audit session
sudo auditctl -s

# List current audit trail files
ls -lht /var/audit/

Enable Auditing

On modern macOS, auditd is typically loaded by default. If it is not running:

# Start the audit daemon
sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.auditd.plist

Configure What to Audit

Edit /etc/security/audit_control to set the flags. A recommended configuration for security monitoring:

# Back up the original
sudo cp /etc/security/audit_control /etc/security/audit_control.bak

# A strong security-focused configuration:
# lo = login/logout
# aa = authentication/authorization
# ad = administrative actions
# pc = process operations
# fc = file creation
# fd = file deletion
# ex = program execution
sudo nano /etc/security/audit_control

After editing, refresh the audit daemon:

sudo audit -s

Warning: Enabling broad audit classes like fr (file read) or fw (file write) on every user generates enormous volumes of data and measurable I/O overhead. Use these selectively with per-user flags or auditreduce filtering rather than system-wide.

Per-User Audit Flags

Override system defaults for specific users by editing /etc/security/audit_user:

# Audit all file operations for a specific admin account
admin_user:fr,fw,fc,fd,ex:no

Reading Audit Logs with praudit

BSM audit trails are binary. The praudit tool converts them to human-readable output:

# Read the most recent audit file in default (raw) format
sudo praudit /var/audit/current

# Read in short (one-line-per-event) format
sudo praudit -s /var/audit/current

# Read in XML format (useful for parsing)
sudo praudit -x /var/audit/current

# Pipe to less for navigation
sudo praudit -s /var/audit/current | less

Understanding Audit Tokens

Each audit record consists of multiple tokens that describe different aspects of the event:

TokenContains
headerRecord length, event type, timestamp
subjectThe user/process that triggered the event (UID, GID, PID, session ID)
returnSuccess or failure status of the system call
pathFile path involved in the event
attributeFile attributes (permissions, owner, inode)
argumentSystem call arguments
exec argCommand-line arguments for executed programs
ip addrNetwork address information
textFree-form text description

A typical raw praudit record looks like this (one event, multiple tokens):

header,88,11,execve(2),0,Fri Feb 14 10:23:45 2026, + 312 msec
exec arg,/usr/bin/sudo
exec arg,log
exec arg,show
exec arg,--last
exec arg,5m
subject,admin_user,root,admin,admin,admin,1234,5678,40,192.168.1.10
return,success,0

This shows user admin_user executing sudo log show --last 5m and succeeding.

Filtering with auditreduce

The auditreduce tool filters binary audit trails before passing them to praudit. This is far more efficient than reading entire files:

# Filter events from a specific user
sudo auditreduce -u admin_user /var/audit/current | praudit -s

# Filter by event class (login/logout only)
sudo auditreduce -c lo /var/audit/current | praudit -s

# Filter by time range
sudo auditreduce -a 20260214090000 -b 20260214100000 /var/audit/current | praudit -s

# Filter for failed events only (useful for detecting brute force)
sudo auditreduce -r 1-255 /var/audit/current | praudit -s

# Combine filters: failed login attempts for a specific user
sudo auditreduce -c lo -u targeted_user -r 1-255 /var/audit/current | praudit -s

# Process all rotated audit files (not just current)
sudo auditreduce -c ex /var/audit/* | praudit -s

Practical Security Monitoring Examples

Detect Failed Authentication Attempts

# All failed login/auth events in the last audit trail
sudo auditreduce -c aa -r 1-255 /var/audit/current | praudit -s

Track Privilege Escalation

# All sudo and su executions
sudo auditreduce -c pc,ex /var/audit/current | praudit -s | grep -E "sudo|su "

Monitor File Deletions

# All file deletion events
sudo auditreduce -c fd /var/audit/current | praudit -s

# File deletions by a specific user
sudo auditreduce -c fd -u suspect_user /var/audit/current | praudit -s

Track Process Execution

# All programs executed (requires ex class to be enabled)
sudo auditreduce -c ex /var/audit/current | praudit -s

# Look for specific suspicious binaries
sudo auditreduce -c ex /var/audit/current | praudit | grep -i "curl\|wget\|nc\|ncat\|python\|osascript"

Investigate a Specific Time Window

When you know an incident occurred around a particular time:

# Extract events from 2:00 PM to 2:30 PM on Feb 14, 2026
sudo auditreduce -a 20260214140000 -b 20260214143000 /var/audit/* | praudit -s > /tmp/incident_window.txt

Connecting BSM to a SIEM

For fleet-wide security monitoring, forward BSM events to a centralized SIEM (Splunk, Elastic, etc.):

XML Export for Ingestion

# Export recent audit events as XML for SIEM ingestion
sudo auditreduce -a 20260214000000 /var/audit/current | praudit -x > /tmp/audit_export.xml

Continuous Forwarding with a LaunchDaemon

Create a script that periodically ships audit data to your SIEM endpoint, or use tools like osquery which can read OpenBSM events natively and forward them in structured JSON format.

# osquery can query BSM events directly
echo "SELECT * FROM process_events LIMIT 10;" | osqueryi --json

Tip: osquery’s process_events and file_events tables consume OpenBSM audit data under the hood. If you already run osquery on your fleet, you may be getting BSM data without realizing it.

BSM vs. Unified Logging

These are complementary systems, not competitors:

AspectBSM AuditUnified Logging
PurposeSecurity audit trailOperational diagnostics
FormatBinary (tamper-evident)Compressed binary
PersistenceAll configured events persistDepends on log level
OverheadModerate (kernel-level)Low (designed for always-on)
Best forCompliance, forensics, incident responseTroubleshooting, debugging, monitoring

For Mac admins responsible for security, the recommendation is clear: use unified logging for daily troubleshooting and BSM auditing for the security audit trail you hope you never need but will be glad you have.

Related Articles