$npx -y skills add BagelHole/DevOps-Security-Agent-Skills --skill audit-loggingImplement centralized audit logging and SIEM integration. Configure log retention and security monitoring. Use when implementing audit trail requirements.
| 1 | # Audit Logging |
| 2 | |
| 3 | Implement comprehensive audit logging for compliance, security monitoring, and forensic analysis across infrastructure and applications. |
| 4 | |
| 5 | ## When to Use |
| 6 | |
| 7 | - Setting up centralized logging for compliance frameworks (SOC 2, HIPAA, PCI DSS) |
| 8 | - Implementing security event monitoring and alerting |
| 9 | - Building audit trails for regulatory requirements |
| 10 | - Configuring log retention and tamper-proof storage |
| 11 | - Integrating application logs with SIEM platforms |
| 12 | |
| 13 | ## Log Categories |
| 14 | |
| 15 | ```yaml |
| 16 | audit_events: |
| 17 | authentication: |
| 18 | - Login attempts (success and failure) |
| 19 | - MFA enrollment and verification events |
| 20 | - Session creation, renewal, and termination |
| 21 | - Password changes and resets |
| 22 | - API key and token generation |
| 23 | |
| 24 | authorization: |
| 25 | - Access grants and denials |
| 26 | - Permission changes and role assignments |
| 27 | - Privilege escalation events |
| 28 | - Resource sharing modifications |
| 29 | - Policy evaluation results |
| 30 | |
| 31 | data_access: |
| 32 | - Read operations on sensitive data |
| 33 | - Write and update operations |
| 34 | - Delete and purge operations |
| 35 | - Bulk export and download events |
| 36 | - Data classification changes |
| 37 | |
| 38 | administrative: |
| 39 | - Configuration changes |
| 40 | - User and group management |
| 41 | - System startup and shutdown |
| 42 | - Backup and restore operations |
| 43 | - Network and firewall rule changes |
| 44 | |
| 45 | system: |
| 46 | - Service health state changes |
| 47 | - Resource provisioning and deprovisioning |
| 48 | - Certificate and key rotation events |
| 49 | - Scheduled job execution results |
| 50 | - Integration and webhook events |
| 51 | ``` |
| 52 | |
| 53 | ## Rsyslog Configuration for Centralized Logging |
| 54 | |
| 55 | ```bash |
| 56 | # /etc/rsyslog.d/50-audit.conf |
| 57 | |
| 58 | # Load imfile module to read application logs |
| 59 | module(load="imfile") |
| 60 | |
| 61 | # Forward auth logs |
| 62 | input(type="imfile" |
| 63 | File="/var/log/auth.log" |
| 64 | Tag="auth" |
| 65 | Severity="info" |
| 66 | Facility="auth" |
| 67 | ) |
| 68 | |
| 69 | # Forward application audit logs |
| 70 | input(type="imfile" |
| 71 | File="/var/log/app/audit.log" |
| 72 | Tag="app-audit" |
| 73 | Severity="info" |
| 74 | Facility="local0" |
| 75 | ) |
| 76 | |
| 77 | # Structured JSON template |
| 78 | template(name="json-audit" type="list") { |
| 79 | constant(value="{") |
| 80 | constant(value="\"@timestamp\":\"") property(name="timereported" dateFormat="rfc3339") |
| 81 | constant(value="\",\"host\":\"") property(name="hostname") |
| 82 | constant(value="\",\"severity\":\"") property(name="syslogseverity-text") |
| 83 | constant(value="\",\"facility\":\"") property(name="syslogfacility-text") |
| 84 | constant(value="\",\"tag\":\"") property(name="syslogtag" format="json") |
| 85 | constant(value="\",\"message\":\"") property(name="msg" format="json") |
| 86 | constant(value="\"}\n") |
| 87 | } |
| 88 | |
| 89 | # Forward to central syslog server over TLS |
| 90 | action( |
| 91 | type="omfwd" |
| 92 | target="syslog.internal.example.com" |
| 93 | port="6514" |
| 94 | protocol="tcp" |
| 95 | StreamDriver="gtls" |
| 96 | StreamDriverMode="1" |
| 97 | StreamDriverAuthMode="x509/name" |
| 98 | template="json-audit" |
| 99 | queue.type="LinkedList" |
| 100 | queue.size="50000" |
| 101 | queue.filename="fwd_audit" |
| 102 | queue.saveonshutdown="on" |
| 103 | action.resumeRetryCount="-1" |
| 104 | ) |
| 105 | ``` |
| 106 | |
| 107 | ## Journald Configuration for Persistent Logging |
| 108 | |
| 109 | ```ini |
| 110 | # /etc/systemd/journald.conf |
| 111 | [Journal] |
| 112 | Storage=persistent |
| 113 | Compress=yes |
| 114 | Seal=yes |
| 115 | SplitMode=uid |
| 116 | MaxRetentionSec=365d |
| 117 | MaxFileSec=30d |
| 118 | SystemMaxUse=10G |
| 119 | SystemKeepFree=2G |
| 120 | ForwardToSyslog=yes |
| 121 | ``` |
| 122 | |
| 123 | ```bash |
| 124 | # Query journald for audit events |
| 125 | journalctl _TRANSPORT=audit --since "24 hours ago" --output json-pretty |
| 126 | |
| 127 | # Filter by specific audit types |
| 128 | journalctl _AUDIT_TYPE=1112 --since today # user login events |
| 129 | journalctl _AUDIT_TYPE=1100 --since today # user auth events |
| 130 | |
| 131 | # Export for offline analysis |
| 132 | journalctl --since "7 days ago" --output export > /backup/journal-export.bin |
| 133 | ``` |
| 134 | |
| 135 | ## Application Logging with Structured JSON |
| 136 | |
| 137 | ```python |
| 138 | import logging |
| 139 | import json |
| 140 | import hashlib |
| 141 | from datetime import datetime, timezone |
| 142 | from functools import wraps |
| 143 | |
| 144 | class AuditLogger: |
| 145 | def __init__(self, service_name, logger_name="audit"): |
| 146 | self.service = service_name |
| 147 | self.logger = logging.getLogger(logger_name) |
| 148 | handler = logging.FileHandler("/var/log/app/audit.log") |
| 149 | handler.setFormatter(logging.Formatter("%(message)s")) |
| 150 | self.logger.addHandler(handler) |
| 151 | self.logger.setLevel(logging.INFO) |
| 152 | self._prev_hash = None |
| 153 | |
| 154 | def log_event(self, event_type, user, resource, action, result, |
| 155 | metadata=None, source_ip=None): |
| 156 | log_entry = { |
| 157 | "timestamp": datetime.now(timezone.utc).isoformat(), |
| 158 | "service": self.service, |
| 159 | "event_type": event_type, |
| 160 | "user": user, |
| 161 | "resource": resource, |
| 162 | "action": action, |
| 163 | "result": result, |
| 164 | "source_ip": source_ip, |
| 165 | "metadata": metadata or {}, |
| 166 | } |
| 167 | # Chain hash for tamper detection |
| 168 | raw = json.dumps(log_entry, sort_keys=True) |
| 169 | log_entry["prev_ |