Cassandra Audit Logging
Audit logging provides a detailed record of database activity for security monitoring, compliance, and forensic analysis. Introduced in Cassandra 4.0, the audit logging feature captures authentication attempts, authorization decisions, and CQL operations.
Overview
Section titled “Overview”Version Requirements
Section titled “Version Requirements”| Feature | Minimum Version |
|---|---|
| Basic audit logging | 4.0 |
| Full query logging (FQL) | 4.0 |
| Enhanced audit logging | 4.1+ |
Pre-4.0 Clusters
Cassandra versions prior to 4.0 do not have built-in audit logging. Third-party solutions or custom implementations using triggers/CDC are required for audit capabilities in older versions.
What Gets Logged
Section titled “What Gets Logged”Audit logging can capture:
| Category | Events | Use Case |
|---|---|---|
| Authentication | Login attempts, failures | Security monitoring |
| Authorization | Permission checks, denials | Access control auditing |
| DCL | GRANT, REVOKE, role changes | Privilege management |
| DDL | CREATE, ALTER, DROP schema | Change management |
| DML | SELECT, INSERT, UPDATE, DELETE | Data access auditing |
| Query | All CQL statements | Compliance, debugging |
Audit Flow Architecture
Section titled “Audit Flow Architecture”Configuration
Section titled “Configuration”Enabling Audit Logging
Section titled “Enabling Audit Logging”Configure audit logging in cassandra.yaml:
# Enable audit loggingaudit_logging_options: enabled: true logger: - class_name: BinAuditLogger
# Categories to audit included_categories: AUTH,DCL,DDL,DML
# Keyspaces to audit (empty = all) included_keyspaces:
# Keyspaces to exclude from auditing excluded_keyspaces: system,system_schema,system_auth,system_distributed,system_traces,system_views
# Users to audit (empty = all) included_users:
# Users to exclude from auditing excluded_users:Audit Categories
Section titled “Audit Categories”| Category | Description | Events Captured |
|---|---|---|
AUTH | Authentication events | Login success/failure, authentication errors |
DCL | Data Control Language | GRANT, REVOKE, CREATE/ALTER/DROP ROLE |
DDL | Data Definition Language | CREATE/ALTER/DROP KEYSPACE/TABLE/INDEX/VIEW/TYPE/FUNCTION |
DML | Data Manipulation Language | SELECT, INSERT, UPDATE, DELETE, BATCH |
QUERY | All queries | Every CQL statement (high volume) |
PREPARE | Prepared statements | PREPARE operations |
ERROR | Query errors | Failed queries, syntax errors |
Production Configuration Example
Section titled “Production Configuration Example”audit_logging_options: enabled: true logger: - class_name: BinAuditLogger
# Top-level BinAuditLogger settings (not under logger.parameters) audit_logs_dir: /var/log/cassandra/audit roll_cycle: HOURLY block: true max_queue_weight: 268435456 # 256 MB max_log_size: 17179869184 # 16 GB archive_command: /usr/local/bin/archive-audit-logs.sh %path
# Recommended: Don't log DML for high-throughput tables included_categories: AUTH,DCL,DDL
# Exclude system keyspaces excluded_keyspaces: system,system_schema,system_auth,system_distributed,system_traces,system_views,system_virtual_schema
# Exclude service accounts from routine logging excluded_users: monitoring_user,backup_userBinAuditLogger Configuration
BinAuditLogger settings (roll_cycle, block, max_queue_weight, max_log_size, archive_command) are top-level fields under audit_logging_options, not under logger.parameters. The logger.parameters section only supports key_value_separator and field_separator for output formatting.
Audit Loggers
Section titled “Audit Loggers”BinAuditLogger (Default)
Section titled “BinAuditLogger (Default)”Binary format logger optimized for performance:
audit_logging_options: enabled: true logger: - class_name: BinAuditLogger # BinAuditLogger settings are top-level, not under logger.parameters audit_logs_dir: /var/log/cassandra/audit roll_cycle: HOURLY block: true max_queue_weight: 268435456 max_log_size: 17179869184Parameters (top-level under audit_logging_options):
| Parameter | Default | Description |
|---|---|---|
audit_logs_dir | ${CASSANDRA_LOG_DIR}/audit | Directory for audit log files |
roll_cycle | HOURLY | Log rotation: MINUTELY, HOURLY, DAILY |
block | true | Block when queue full (vs drop events) |
max_queue_weight | 256 MB | Maximum memory for pending events |
max_log_size | 16 GB | Maximum total log size before archiving |
archive_command | none | Command to run when rotating logs |
Reading Binary Logs:
# Use auditlogviewer tool to read binary logsauditlogviewer /var/log/cassandra/audit/
# Filter by time rangeauditlogviewer /var/log/cassandra/audit/ --from "2024-01-15 00:00:00" --to "2024-01-15 23:59:59"
# Output to fileauditlogviewer /var/log/cassandra/audit/ > audit_readable.logFileAuditLogger
Section titled “FileAuditLogger”Human-readable text format (higher overhead):
audit_logging_options: enabled: true logger: - class_name: FileAuditLoggerLogs to standard Cassandra log file in readable format:
INFO [Native-Transport-Requests-1] AuditLog.java:89 - user:alice|host:192.168.1.100:9042|source:192.168.1.50|port:52431|timestamp:1705315800000|type:SELECT|category:DML|keyspace:production|table:users|operation:SELECT * FROM production.users WHERE user_id = ?Custom Audit Logger
Section titled “Custom Audit Logger”Implement custom logging for integration with external systems:
public class SyslogAuditLogger implements IAuditLogger {
@Override public void log(AuditLogEntry entry) { // Send to syslog, SIEM, or external system String message = formatEntry(entry); syslogClient.send(message); }
@Override public void stop() { syslogClient.close(); }
@Override public boolean isEnabled() { return true; }}audit_logging_options: enabled: true logger: - class_name: com.example.SyslogAuditLogger parameters: - syslog_host: syslog.example.com - syslog_port: 514 - facility: LOCAL0Filtering
Section titled “Filtering”Keyspace Filtering
Section titled “Keyspace Filtering”audit_logging_options: enabled: true
# Only audit specific keyspaces included_keyspaces: production,sensitive_data
# Or exclude specific keyspaces (if included_keyspaces is empty) excluded_keyspaces: system,system_schema,development,testUser Filtering
Section titled “User Filtering”audit_logging_options: enabled: true
# Only audit specific users included_users: admin_alice,admin_bob,app_production
# Or exclude specific users (if included_users is empty) excluded_users: monitoring_service,healthcheck_userKeyspace-Level Filtering Only
Section titled “Keyspace-Level Filtering Only”No Table-Level Filtering
Cassandra audit logging does not support table-level filtering (included_tables / excluded_tables). Filtering is available at the keyspace, user, and category levels only.
Category-Based Filtering
Section titled “Category-Based Filtering”audit_logging_options: enabled: true
# Compliance minimum: Auth + privilege changes included_categories: AUTH,DCL
# Security monitoring: Add schema changes included_categories: AUTH,DCL,DDL
# Full audit (high volume) included_categories: AUTH,DCL,DDL,DML,QUERYAudit Log Format
Section titled “Audit Log Format”Log Entry Fields
Section titled “Log Entry Fields”Each audit log entry contains:
| Field | Description | Example |
|---|---|---|
user | Authenticated user | alice |
host | Coordinator node | 192.168.1.100:9042 |
source | Client IP address | 192.168.1.50 |
port | Client port | 52431 |
timestamp | Event time (epoch ms) | 1705315800000 |
type | Operation type | SELECT, INSERT, CREATE_TABLE |
category | Event category | DML, DDL, AUTH |
keyspace | Target keyspace | production |
table | Target table (if applicable) | users |
operation | Full CQL statement | SELECT * FROM users WHERE id = ? |
batch_id | Batch identifier (if batch) | abc123-def456 |
Sample Log Entries
Section titled “Sample Log Entries”Authentication Success:
user:alice|host:192.168.1.100:9042|source:192.168.1.50|port:52431|timestamp:1705315800000|type:LOGIN_SUCCESS|category:AUTHAuthentication Failure:
user:unknown|host:192.168.1.100:9042|source:10.0.0.99|port:54321|timestamp:1705315801000|type:LOGIN_ERROR|category:AUTH|operation:Provided username unknown and/or password are incorrectDDL Operation:
user:schema_admin|host:192.168.1.100:9042|source:192.168.1.60|port:52500|timestamp:1705315802000|type:CREATE_TABLE|category:DDL|keyspace:production|operation:CREATE TABLE production.new_table (id UUID PRIMARY KEY, data TEXT)DML Operation:
user:app_service|host:192.168.1.100:9042|source:192.168.1.70|port:52600|timestamp:1705315803000|type:SELECT|category:DML|keyspace:production|table:users|operation:SELECT * FROM production.users WHERE user_id = ?Permission Change:
user:security_admin|host:192.168.1.100:9042|source:192.168.1.80|port:52700|timestamp:1705315804000|type:GRANT|category:DCL|operation:GRANT SELECT ON KEYSPACE production TO analyst_roleFull Query Logging (FQL)
Section titled “Full Query Logging (FQL)”Full Query Logging captures complete query details for debugging and replay:
Enabling FQL
Section titled “Enabling FQL”# Enable via nodetoolnodetool enablefullquerylog --path /var/log/cassandra/fql
# With optionsnodetool enablefullquerylog \ --path /var/log/cassandra/fql \ --roll-cycle HOURLY \ --max-log-size 1073741824 \ --blocking trueFQL vs Audit Logging
Section titled “FQL vs Audit Logging”| Aspect | Audit Logging | Full Query Logging |
|---|---|---|
| Purpose | Security, compliance | Debugging, replay |
| Format | Structured events | Binary query log |
| Filtering | Category, user, keyspace | None (all queries) |
| Performance | Lower overhead | Higher overhead |
| Tooling | auditlogviewer | fqltool |
| Use case | Long-term retention | Short-term analysis |
Reading FQL
Section titled “Reading FQL”# Dump FQL to readable formatfqltool dump /var/log/cassandra/fql/
# Replay queries against another clusterfqltool replay \ --keyspace production \ --target 192.168.2.100 \ /var/log/cassandra/fql/
# Compare query results between clustersfqltool compare \ --keyspace production \ --target1 192.168.1.100 \ --target2 192.168.2.100 \ /var/log/cassandra/fql/Runtime Management
Section titled “Runtime Management”Enable/Disable Audit Logging
Section titled “Enable/Disable Audit Logging”# Enable audit logging at runtimenodetool enableauditlog
# With specific categoriesnodetool enableauditlog --included-categories AUTH,DCL,DDL
# With keyspace filternodetool enableauditlog --included-keyspaces production,sensitive
# Disable audit loggingnodetool disableauditlogCheck Audit Logging Status
Section titled “Check Audit Logging Status”# View current audit logging statusnodetool getauditlogLog Rotation
Section titled “Log Rotation”Audit log rotation is handled automatically by the roll_cycle setting. There is no nodetool command to force audit log rotation. For custom archival, use the archive_command setting or external log rotation tools.
FQL vs Audit Logs
nodetool resetfullquerylog resets Full Query Logging (FQL), not audit logs. FQL and audit logging are separate features.
SIEM Integration
Section titled “SIEM Integration”Custom Syslog Integration
Section titled “Custom Syslog Integration”# cassandra.yaml - custom loggeraudit_logging_options: enabled: true logger: - class_name: com.example.SyslogAuditLogger parameters: - syslog_host: siem.example.com - syslog_port: 514 - syslog_protocol: TCP - syslog_facility: AUTHCompliance Considerations
Section titled “Compliance Considerations”PCI DSS Requirements
Section titled “PCI DSS Requirements”| Requirement | Implementation |
|---|---|
| 10.1 | Enable audit logging for all authentication |
| 10.2.1 | Log all individual user access to cardholder data |
| 10.2.2 | Log all actions by anyone with admin privileges |
| 10.2.4 | Log invalid access attempts |
| 10.2.5 | Log changes to authentication mechanisms |
| 10.3 | Include user ID, event type, date/time, success/fail, origin, resource |
| 10.5 | Secure audit logs (separate storage, access controls) |
| 10.7 | Retain logs for at least one year |
Recommended PCI DSS Configuration
Section titled “Recommended PCI DSS Configuration”audit_logging_options: enabled: true logger: - class_name: BinAuditLogger parameters: - log_dir: /secure/audit/cassandra - roll_cycle: DAILY - max_log_size: 107374182400 # 100 GB - archive_command: /usr/local/bin/secure-archive.sh %path
included_categories: AUTH,DCL,DDL,DML excluded_keyspaces: system,system_schema,system_distributed,system_traces # Log all users - don't exclude any for PCISOC 2 Requirements
Section titled “SOC 2 Requirements”| Control | Implementation |
|---|---|
| CC6.1 | Log all logical access |
| CC6.2 | Log authentication events |
| CC7.2 | Monitor for unauthorized access |
| CC7.3 | Log configuration changes |
HIPAA Audit Controls
Section titled “HIPAA Audit Controls”| Requirement | Implementation |
|---|---|
| Access logging | Enable DML auditing for PHI keyspaces |
| User identification | Log authenticated user for all queries |
| Integrity controls | Use secure log storage with checksums |
| Retention | Retain logs for 6 years minimum |
Performance Impact
Section titled “Performance Impact”Overhead Estimates
Section titled “Overhead Estimates”| Configuration | Performance Impact |
|---|---|
| AUTH only | < 1% |
| AUTH + DCL + DDL | 1-2% |
| AUTH + DCL + DDL + DML | 5-15% |
| All categories (QUERY) | 15-30% |
Minimizing Impact
Section titled “Minimizing Impact”- Filter aggressively: Only audit what compliance requires
- Exclude high-volume tables: Metrics, logs, time-series
- Exclude service accounts: Monitoring, health checks
- Use async logging: Set
block: false(may lose events) - Adequate disk I/O: Use fast storage for audit logs
- Separate disk: Don't compete with data I/O
# High-performance configurationaudit_logging_options: enabled: true logger: - class_name: BinAuditLogger parameters: - log_dir: /fast-ssd/audit # Dedicated fast storage - block: false # Don't block on full queue - max_queue_weight: 536870912 # 512 MB queue
included_categories: AUTH,DCL,DDL # No DML excluded_keyspaces: system,system_schema,metrics,logs excluded_users: monitoring,healthcheckLog Management
Section titled “Log Management”Retention Policy
Section titled “Retention Policy”#!/bin/bashLOG_PATH=$1ARCHIVE_DIR=/archive/cassandra-auditRETENTION_DAYS=365
# Compress and archivegzip -c "$LOG_PATH" > "$ARCHIVE_DIR/$(basename $LOG_PATH).gz"
# Remove originalrm "$LOG_PATH"
# Clean old archivesfind "$ARCHIVE_DIR" -name "*.gz" -mtime +$RETENTION_DAYS -deleteLog Rotation with logrotate
Section titled “Log Rotation with logrotate”/var/log/cassandra/audit/*.log { daily rotate 30 compress delaycompress missingok notifempty create 640 cassandra cassandra postrotate /usr/bin/nodetool resetfullquerylog 2>/dev/null || true endscript}Troubleshooting
Section titled “Troubleshooting”Audit Logs Not Writing
Section titled “Audit Logs Not Writing”# Check if audit logging is enablednodetool getauditlog
# Verify directory permissionsls -la /var/log/cassandra/audit/
# Check for errors in system.loggrep -i audit /var/log/cassandra/system.logHigh Disk Usage
Section titled “High Disk Usage”# Check audit log sizedu -sh /var/log/cassandra/audit/
# Verify archive command is workingcat /var/log/cassandra/system.log | grep archive
# Force cleanup if needednodetool disableauditlogrm -rf /var/log/cassandra/audit/*nodetool enableauditlogPerformance Degradation
Section titled “Performance Degradation”# Reduce audit scopeaudit_logging_options: included_categories: AUTH,DCL # Remove DDL, DML
# Or exclude high-volume sources excluded_keyspaces: metrics,logs,events excluded_users: etl_service,batch_processorRelated Documentation
Section titled “Related Documentation”- Authorization - Role-based access control
- Authentication - User authentication
- Security Overview - Complete security guide