ruby 65 lines · 3 tabs

Audit logging for sensitive operations

Alex Kumar Jan 2026
3 tabs
class CreateAuditLogs < ActiveRecord::Migration[6.1]
  def change
    create_table :audit_logs do |t|
      t.references :user, null: true, foreign_key: true
      t.string :action, null: false
      t.string :resource_type
      t.bigint :resource_id
      t.jsonb :metadata, default: {}
      t.jsonb :changes, default: {}
      t.inet :ip_address
      t.string :user_agent
      t.timestamp :created_at, null: false
    end

    add_index :audit_logs, [:resource_type, :resource_id]
    add_index :audit_logs, :action
    add_index :audit_logs, :created_at
    add_index :audit_logs, :metadata, using: :gin
  end
end
3 files · ruby Explain with highlit

Audit logs provide accountability and forensic capabilities for sensitive operations like permission changes, data deletion, or financial transactions. I store audit events in a dedicated table with who performed the action, what changed, when it occurred, and the request context (IP, user agent). For data changes, I use paper_trail gem to track all versions of critical models automatically. Each audit entry includes a JSON payload with before/after states so I can reconstruct history or implement undo functionality. Audit logs are write-only and never deleted—I archive old entries to cold storage but retain them indefinitely for compliance. For GDPR, I pseudonymize user identifiers while maintaining the ability to reconstruct events.


Related snips

Share this code

Here's the card — post it anywhere.

Audit logging for sensitive operations — share card
Link copied