Skip to content

Audit log

Every write operation (create, update, delete) on relevant tables lands in audit_log. With diff between old and new, with author, with timestamp.

Contents

Field Meaning
id Entry UUID
tenant_id Tenant scope
user_id who did it (NULL for system actions)
action host.create, alert_rule.update, dashboard.delete, …
target_kind host, alert_rule, dashboard, …
target_id UUID of affected resource
old_values JSONB pre-change
new_values JSONB post-change
created_at time
ip user's IP

old_values and new_values are filled by track_change — a small helper converting SQLAlchemy models to dicts and masking sensitive fields.

Instrumented routes

These routes write audit entries:

  • Hosts (create, update, delete)
  • Host services (create, update, delete, ack, downtime set)
  • Tenants
  • Alert rules
  • Notification channels
  • Dashboards
  • Monitoring scripts
  • Profiles + profile-checks
  • Users + roles

Login / logout / failed-login are also logged with action = auth.login_success / auth.login_failed.

Redacted fields

AUDIT_FIELD_BLACKLIST (in api/app/audit.py):

  • password_hash
  • two_fa_secret
  • token_hash
  • key_hash
  • snmp_community
  • ssh_password
  • private_key

These appear as "***" in the audit log — even when changed, never as plaintext.

Diff view

/audit-log → collapsible rows with diff highlighting:

- alert_rule_threshold_warn:  80
+ alert_rule_threshold_warn:  50
- alert_rule_channels:        ["ops-email"]
+ alert_rule_channels:        ["ops-email", "ops-push"]

Red/green colored, old/new side by side.

Filters

Filter Example
Action only delete actions
Target kind only host
Target ID only changes to a specific host
User who did it
Time last 24 h, last 30 d, custom

Filters persist in URL: /audit-log?action=delete&target_kind=host.

Audit on host detail

Per host: Audit tab shows entries with target_id = <hostId>. Useful for „what happened to this host?" on one page.

Retention

Tier Default retention
Community 30 days
Pro 90 days
Enterprise configurable up to unlimited

Auto-purge runs daily. For longer retention: regular audit export (CSV / JSON) to external storage.

Export

curl -H "Authorization: Bearer <JWT>" \
  "https://your-domain.tld/api/v1/audit-log/export?from=2026-04-01&format=csv" \
  > audit-april.csv

Format: CSV or JSON, all fields.

Security

  • Audit log is read-only via UI — no edit/delete endpoints
  • DB-side: no UPDATE triggers on audit_log (except system migrations)
  • Backups include audit log — restoring an old backup loses recent entries

Permissions

Permission Effect
audit.view View audit log
audit.export CSV/JSON export
audit.purge Manually delete older-than-X (super admin only)

Compliance

When an auditor asks „who changed the threshold of service X on date Y?":

  • /audit-log?target_id=<service-uuid>&action=update
  • Sort by date, expand each
  • Diff shows old and new values
  • Author and IP visible

Sufficient for most ISO 27001 audits.

Next