<div class="docs-content" data-render>
# 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 (155 across 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.
</div>