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 (
GETendpoints). - Internal heartbeats and evidence reports from the daemon.
- WebSocket fanout.
Related routes¶
- Every section of the dashboard links into Audit with a pre-applied resource filter when "history" is requested.