infrastructure.persistence.models.audit_log¶
src.infrastructure.persistence.models.audit_log
¶
Audit log database model for compliance tracking.
This module defines the AuditLog model for storing immutable audit trail records. Used for PCI-DSS, SOC 2, and GDPR compliance.
CRITICAL: This table is IMMUTABLE. Records cannot be modified or deleted. Immutability is enforced by PostgreSQL RULES in the migration.
Classes¶
AuditLog
¶
Bases: BaseModel
Audit log model - IMMUTABLE (cannot be updated or deleted).
This model stores all audit trail records for compliance and security forensics. Records are append-only and cannot be modified after creation.
Immutability Enforcement
- Database level: PostgreSQL RULES block UPDATE/DELETE operations
- Application level: No update methods in repository
- See migration: add_audit_logs_table for RULES definition
Known Limitation
- TRUNCATE bypasses RULES (table owner can TRUNCATE)
- For development: TRUNCATE should only be used for testing cleanup
- For production: Implement separate owner user (see roadmap)
Compliance
- PCI-DSS: 7+ year retention, immutable audit trail
- SOC 2: Security event tracking (who/what/when/where)
- GDPR: Personal data access tracking
Fields
id: UUID primary key (from BaseModel) created_at: Timestamp when logged (from BaseModel, immutable) action: What happened (e.g., "user_login", "password_changed") user_id: Who performed the action (None for system actions) resource_type: What was affected (e.g., "user", "account", "provider") resource_id: Specific resource identifier (optional) ip_address: Where from (required for auth events) user_agent: Client information context: Additional event context (JSONB - extensible)
Indexes
- idx_audit_user_action: (user_id, action) for user activity queries
- idx_audit_resource: (resource_type, resource_id) for resource audits
- created_at: Indexed via BaseModel for time-range queries
Note
This model inherits from BaseModel (NOT BaseMutableModel) because audit logs are immutable and should not have updated_at field.
Example
Create audit log (via repository)¶
audit_log = AuditLogModel( action="user_login", user_id=user_id, resource_type="session", ip_address="192.168.1.1", user_agent="Mozilla/5.0...", context={"method": "password", "mfa": True}, ) session.add(audit_log) await session.commit()
Query audit logs¶
result = await session.execute( select(AuditLogModel) .where(AuditLogModel.user_id == user_id) .order_by(AuditLogModel.created_at.desc()) .limit(100) ) logs = result.scalars().all()
Source code in src/infrastructure/persistence/models/audit_log.py
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | |