# ADR-0020: Audit Logging Storage ## Status Accepted ## Context The platform needs to audit all security-relevant actions: - User logins and authentication attempts - Permission changes - Data modifications - Administrative actions Audit logs must be: - Immutable (append-only) - Queryable - Performant (don't slow down operations) - Compliant with audit requirements Storage options considered: 1. **PostgreSQL table** - Simple, queryable, transactional 2. **Elasticsearch** - Excellent for searching, but additional dependency 3. **File-based logs** - Simple but hard to query 4. **External audit service** - Overkill for initial version ## Decision Store audit logs in **PostgreSQL append-only table** with JSON metadata: 1. **Table structure**: `audit_logs` with columns: - `id`, `actor_id`, `action`, `target_id`, `metadata` (JSONB), `timestamp` 2. **Append-only**: No UPDATE or DELETE operations 3. **JSON metadata**: Flexible storage for additional context 4. **Indexing**: Index on `actor_id`, `action`, `timestamp` for queries **Rationale:** - Simple (no additional infrastructure) - Queryable via SQL - Transactional (consistent with other data) - JSONB provides flexibility for metadata - Can migrate to Elasticsearch later if needed - Good performance for typical audit volumes ## Consequences ### Positive - Simple implementation - Queryable via SQL - No additional infrastructure - Transactional consistency - Can archive old logs if needed ### Negative - Adds load to primary database - May need archiving strategy for large volumes - Less powerful search than Elasticsearch ### Implementation Notes - Create `audit_logs` table via Ent schema - Use JSONB for metadata column (PostgreSQL-specific) - Add indexes: `(actor_id, timestamp)`, `(action, timestamp)` - Implement async logging (optional, via channel) for high throughput - Consider partitioning by date for large volumes - Add retention policy (e.g., archive after 1 year)