14. Audit Logging

Chapter 14 of 16 · 15 min

Audit logging records security-relevant events for detection, investigation, and compliance. For AI systems, key events include: authentication attempts, API requests, data access, configuration changes, and errors.

What to log:

Authentication events: Login attempts (success and failure), API key usage, session creation and termination.

Data access: Queries processed, documents retrieved, conversation history accessed.

Administrative actions: Configuration changes, model deployments, permission modifications.

Security events: Rate limit triggers, blocked requests, detected injection attempts.

Malfunctions: Errors, exceptions, unexpected model behavior.

Logging implementation:

import logging
import json
from datetime import datetime

class AuditLogger:
    def __init__(self, log_file: str = "/var/log/ai-audit.log"):
        self.logger = logging.getLogger("ai-audit")
        self.logger.setLevel(logging.INFO)
        
        # File handler with rotation
        handler = logging.handlers.RotatingFileHandler(
            log_file, maxBytes=10_000_000, backupCount=5
        )
        handler.setFormatter(logging.Formatter(
            '%(asctime)s %(message)s'
        ))
        self.logger.addHandler(handler)
        
        # Structured JSON output for SIEM integration
        self.json_handler = logging.handlers.RotatingFileHandler(
            "/var/log/ai-audit.json", maxBytes=10_000_000, backupCount=5
        )
        self.json_handler.setFormatter(JsonFormatter())
        self.logger.addHandler(self.json_handler)
    
    def log(self, event_type: str, user: str, details: dict):
        self.logger.info(json.dumps({
            "timestamp": datetime.utcnow().isoformat(),
            "event_type": event_type,
            "user": user,
            "details": details,
            "source_ip": details.get("ip", "unknown")
        }))
    
    def log_auth(self, user: str, success: bool, ip: str, reason: str = ""):
        self.log("authentication", user, {
            "success": success,
            "ip": ip,
            "reason": reason
        })
    
    def log_api_request(self, user: str, endpoint: str, model: str, 
                        prompt_length: int, response_time_ms: int):
        self.log("api_request", user, {
            "endpoint": endpoint,
            "model": model,
            "prompt_length": prompt_length,
            "response_time_ms": response_time_ms
        })

Log retention and protection:

# Configure log retention (90 days for audit logs)
sudo journalctl --vacuum-time=90d

# Protect logs from tampering
sudo chmod 640 /var/log/ai-audit.log
sudo chattr +a /var/log/ai-audit.log  # Append-only (if filesystem supports)

# Ship logs to central SIEM
# Configure Filebeat or Fluentd to forward to Elasticsearch/Splunk

Local verification checkpoint

Run the smallest example from this chapter in a local workspace and record the package version, runtime, data path, and observed output. If the result depends on model size, vector count, CPU/GPU backend, or available memory, note that constraint beside the exercise so the lesson remains reproducible.

EXERCISE

Enable logging in your AI service for authentication and API requests. Generate test logs by making several API calls with valid and invalid credentials. Verify logs appear with correct timestamps and details.