Skip to content

Audit

Immutable record of every state-changing action in the tenant.

Route: /audit Role gating: read for all (records are tenant-scoped).

Model

Each row is appended once and never modified.

Field Notes
Resource type incident, server, recipe, policy, agent, user, tenant, secret, etc.
Resource ID UUID of the affected row, or NULL for system events
Action created, updated, deleted, executed, approved, auth.login, auth.login_failed, etc.
Actor User email or agent:<name>; NULL for unauthenticated events such as failed logins
Tenant Nullable — system events (e.g., failed logins from unknown emails) carry tenant_id = NULL
Timestamp UTC, second precision
Detail JSON blob with the diff or change summary
IP address Captured from X-Forwarded-For only when the immediate peer is in trusted (RFC1918 / loopback) space; otherwise the actual TCP peer

Filters

  • Querystring ?resource_type=… filters by type.
  • Querystring ?resource_id=… filters by specific resource. The rest of the dashboard links here for "what changed on this resource?"
  • Free-text search on actor and action.

Guardian audit actions

OpenRemedy Guardian writes the following actions:

Action When Detail
guardian.elevated_risk Hook B raises a recipe's effective risk before the approval gate from, to, guardian_severity, recipe_slug
guardian.comment_flagged Hook C detects medium+ severity in a human comment on an incident severity
tenant.guardian_fail_mode.updated Admin changes the Guardian fail-mode setting in Settings fail_mode

Hook A (advisory classification at incident creation) is timeline-only; it does not write an audit row.


What is NOT audited

  • Read-only requests (GET endpoints).
  • Internal heartbeats and evidence reports from the daemon.
  • WebSocket fanout.
  • Every section of the dashboard links into Audit with a pre-applied resource filter when "history" is requested.