Module guide
Audit log
Append-only record of every consequential action, per tenant.
Overview
Every service that mutates state calls recordAudit() to append a row with the actor identity, action name (for example, "task.updated"), target (for example, "task:xyz"), and free-form context. Under impersonation the row is stamped with actingAs. This drives automations (when-then), exports (CSV and JSON), and compliance replays.
Highlights
The capabilities worth knowing before you dive in.
- BigInt autoincrement id, so ordering is unambiguous under concurrency
- Indexed by (tenantId, at), (tenantId, actorId), and (tenantId, action)
- Search UI with an action-prefix filter and an actor filter
- Feeds the automation engine and the webhook dispatcher
Important to know
Limits, permissions, and sharp edges to keep in mind.
- Audit events are append-only; they are never mutated or deleted.
- The context JSON can carry arbitrary metadata, so keep PII out.
- Under super-admin impersonation, actingAs is stamped server-side and cannot be spoofed by the client.
How to use it
The primary workflow, start to finish.
- Open /settings/audit-log.
- Filter by an action prefix (for example, "task.") or by actor.
- Export to CSV or JSON for external analysis.
FAQ
- Can an audit entry be edited or removed?
- No. The log is append-only. Entries are never mutated and never deleted, which is what makes it usable as evidence rather than as a convenience.
- Can I tell when somebody acted through impersonation?
- Yes. The acting identity is stamped on the row by the server and cannot be set by the client, so an action taken while impersonating carries both the account it was taken as and the operator who took it.
- Is it safe to put anything I like in the context field?
- The context accepts arbitrary metadata, which means it will faithfully keep whatever you put there, including personal data you did not intend to retain. Keep personal data out of it and record identifiers instead.
Automate this module
Everything on this screen is scriptable. Drive it from the REST API, or let an AI agent run it through the MCP server.
Was this page helpful?