Ferricstore.AuditLog (ferricstore v0.3.5)

Copy Markdown View Source

ETS-backed ring buffer that records security-relevant events.

Mirrors the SlowLog facility in design: a GenServer owns a named ETS table and exposes a simple public API for logging and querying audit events.

Event types

  • :auth_success -- successful AUTH command (username, client IP)
  • :auth_failure -- failed AUTH attempt (username, client IP)
  • :config_change -- CONFIG SET mutation (parameter, old/new values)
  • :connection_open -- new client TCP connection (client IP)
  • :connection_close -- client disconnection (client IP, duration)
  • :dangerous_command -- execution of FLUSHDB, FLUSHALL, or DEBUG
  • :command_denied -- ACL command denial (username, command, client IP)

Configuration (application env)

  • :audit_log_enabled -- boolean, default false. When false, log/2 is a no-op.
  • :audit_log_max_entries -- maximum entries in the ring buffer, default 128. When full, the oldest entry is evicted.

Ownership

This module is a GenServer that owns the ETS table :ferricstore_audit_log. It must be started in the application supervision tree before any connection handler calls log/2.

ACL LOG command

The ACL LOG Redis command is wired to read from this audit log:

  • ACL LOG -- returns all entries (up to max_entries)
  • ACL LOG COUNT n -- returns the last n entries
  • ACL LOG RESET -- clears all entries

Summary

Types

Details map attached to an audit event.

A single audit log entry.

Supported audit event types.

Functions

Returns a specification to start this module under a supervisor.

Returns whether audit logging is currently enabled.

Formats audit log entries into the list-of-maps structure returned by the ACL LOG command.

Returns the last count audit log entries, newest first.

Returns the number of entries currently in the audit log.

Records a security-relevant event in the audit log.

Returns the configured maximum number of entries.

Clears all entries from the audit log and resets the ID counter.

Starts the AuditLog GenServer and creates the backing ETS table.

Types

details()

@type details() :: %{optional(atom()) => term()}

Details map attached to an audit event.

entry()

@type entry() ::
  {id :: non_neg_integer(), timestamp_us :: integer(), event_type(), details()}

A single audit log entry.

event_type()

@type event_type() ::
  :auth_success
  | :auth_failure
  | :config_change
  | :connection_open
  | :connection_close
  | :dangerous_command
  | :command_denied

Supported audit event types.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

enabled?()

@spec enabled?() :: boolean()

Returns whether audit logging is currently enabled.

format_entries(entries)

@spec format_entries([entry()]) :: [list()]

Formats audit log entries into the list-of-maps structure returned by the ACL LOG command.

Each entry is converted to a flat list of alternating key-value pairs, matching Redis ACL LOG output format:

[id, timestamp, event_type_string, details_string, ...]

get(count \\ nil)

@spec get(non_neg_integer() | nil) :: [entry()]

Returns the last count audit log entries, newest first.

When count is nil or omitted, returns all entries up to max_entries.

len()

@spec len() :: non_neg_integer()

Returns the number of entries currently in the audit log.

log(event_type, details)

@spec log(event_type(), details()) :: :ok

Records a security-relevant event in the audit log.

When audit logging is disabled (:audit_log_enabled is false), this function is a no-op and returns :ok immediately.

Parameters

  • event_type -- one of the supported event type atoms
  • details -- a map of event-specific details

Examples

AuditLog.log(:auth_success, %{username: "default", client_ip: "127.0.0.1"})
AuditLog.log(:dangerous_command, %{command: "FLUSHDB", args: []})

max_entries()

@spec max_entries() :: pos_integer()

Returns the configured maximum number of entries.

reset()

@spec reset() :: :ok

Clears all entries from the audit log and resets the ID counter.

start_link(opts \\ [])

@spec start_link(keyword()) :: GenServer.on_start()

Starts the AuditLog GenServer and creates the backing ETS table.