# Audit Log The audit log is the authoritative, append-only record of every state-changing action on the platform: who acted, in which role, from where, on which objects, what changed, and when. It is **administrator-only**: the viewer, its routes, and every monetary figure it records are restricted to admins. > This page is visible to administrators only. ## Viewing the log - **`/admin/audit-log`** lists events newest-first, 25 per page, with the same pagination and table styling as the rest of the admin panel. The sidebar entry sits just above Settings. - A filter bar narrows the list by free-text search (summary, event key, target), category, event key, actor role, origin, result, and a date range. Filters are carried through pagination links. - **`/admin/audit-log/{uid}`** is the per-event detail page: the full row, the old to new value transition, pretty-printed JSON metadata, and a table of related objects (actor, target, parent, author, recipient, source, destination, schedule, instance, setting, job, and more). Both routes negotiate content: send `Accept: application/json` to receive the structured `AuditLogOut` / `AuditEventOut` payload instead of HTML. ## What is recorded Every event carries WHO (`actor_kind`, `actor_uid`, `actor_username`, `actor_role`), FROM WHERE (`origin`, `via_agent`, `request_method`, `request_path`, `actor_ip`, `user_agent`), the primary object (`target_type`, `target_uid`, `target_label`), the change (`old_value` to `new_value`), a sanitised `summary`, event-specific `metadata`, and a `result` of `success`, `failure`, or `denied`. A second table, `audit_log_links`, records each related object with a labelled relation, so an event can reference any number of objects. The complete catalogue of event keys (201 across 35 domains including authentication, content, votes, projects, files, news, admin, services, containers, ingress, AI, the Devii agent, the CLI, rewards, and security) is enumerated in `events.md` at the repository root. ## Security model - **Admin-only.** The list and detail routes are gated by `require_admin`; non-admins receive a redirect (or a 403 for JSON). Financial values (cost, pricing, spend) are recorded for completeness but only surfaced on this admin-only page. - **Append-only.** Rows are never updated. The only deletion is the retention sweep. - **Best-effort.** Recording never raises into a request handler. A failure to write an audit row is logged and swallowed, so the audited action is never blocked. - **Failures and denials are events too.** Authentication failures, authorisation denials, read-only write attempts, self-role-change and self-disable attempts, and quota blocks are all recorded with `result` set to `failure` or `denied`. - **Agent attribution.** When the Devii agent performs a platform mutation, the same event key is recorded with `origin=devii` and `via_agent=1` (the agent's HTTP client sends an `X-Devii-Agent` header), so an auditor can answer "what did the agent do on my behalf" without a parallel taxonomy. Mechanics with no HTTP equivalent get `devii.*` keys. ## Retention Rows older than `audit_log_retention_days` (default 90) are pruned daily by the **Audit retention** background service, configurable on the Services page. Set the retention to `0` to disable pruning entirely.