Audit Log
The forensic substrate the rest of the compliance surface stacks on. Every tool call, every hook firing, every policy decision lands as one row.
Sidebar → Compliance → Audit Log — at /admin/audit on your gateway. The page renders a filterable, paginated log viewer over the canonical row format: actor, service, action, inbound bytes, outbound bytes, result, timestamp. Click any row to expand the full event detail; no wrap toggle — long payloads stay collapsed until needed.
The canonical row
The audit row is deliberately small and discipline-focused:
- Actor — a SHA-256 pseudonym of the authenticated user. Stable across calls (so you can correlate a single user’s pattern) but reversibly identifying only via the gateway’s own actor-mapping, which lives behind the admin gate.
- Service — the upstream the call reached, e.g.
jira,gitlab,google_workspace. - Action — the specific action inside the service tool, e.g.
get_issue,send_email. - Inbound / outbound bytes — the actual payload sizes. Inbound is what the agent sent; outbound is what the upstream returned. The audit log records that something happened and how big it was, not its contents — a deliberate split that keeps the log itself from becoming a privacy hazard.
- Result — HTTP status from the upstream, plus a severity flag (
greenfor success,redfor failures,yellowfor warnings and admin events). - Timestamp — UTC, microsecond resolution.
- Optional event-specific detail — rendered as a key/value strip on expand. Used for things the row schema does not have a slot for: a destructive-action enable, an OAuth refresh failure, a PII scrub statistic.
Severity model
Three colours, one source of truth:
- Green — the call succeeded. Most rows.
- Yellow — non-error operational signals: a destructive action enabled, a threshold breach, a hook deny matched, an admin-approval-blocked attempt.
- Red — failures. Tool calls that returned an error from the upstream, OAuth refresh failures, PII scrub mismatches.
The colour is the same one used by the Action Usage failure-link — clicking a non-zero failed-count cell scopes the audit log to severity=red for that (tool, action) pair in the same window.
Filtering
Top-of-page toolbar accepts:
- Severity — green / yellow / red.
- From / To — a date range. Granularity at the audit-filter level is one day; for sub-day windows use the time-window dashboards (Data Usage, Action Usage) and follow their failure-link to land here pre-filtered.
- Tool — restrict to one service’s read or write tool.
- Action — restrict to one action name inside the chosen tool.
- Actor — restrict to one pseudonymised user. Useful when investigating a specific report.
- Event type —
MCP_TOOL_CALLED,HIGH_RISK_BLOCKED,HIGH_RISK_EXECUTION,CONSENT_DECLINED,THROUGHPUT_READ,OAUTH_REFRESH_FAILED, etc. The taxonomy is documented in the row-expand panel.
Click-to-expand row detail
The default row view is one line per event: timestamp, actor, service, action, bytes, result. Clicking a row expands the full event detail panel inline. Long payload values stay collapsed until needed; no wrap toggle — the constraint was deliberate, the wrap toggle was an early UX experiment that admins consistently asked to remove.
Retention
The audit log holds 90 days. Older events fall out of the bucket store as the retention sweep advances. The dashboard never claims to read further back than that. If you need a longer trail, the standard pattern is to ship a daily CSV export to your own SIEM or archive.
What it is not
The audit log is not a content store. It records that a call happened and how big it was, not what was in it. An audit log full of payload bodies is itself a privacy hazard — an attacker who exfiltrates the log gets a second copy of everything. A byte-count log is operationally just as useful for forensic work and structurally safer to keep.
The audit log is also not a debug log. The application-level gateway_get_logs tool tails the in-memory app log for the current process; the audit log is the persisted forensic surface.
Where it lives in the admin panel
| What | Where in the admin |
|---|---|
| Audit log viewer | Compliance → Audit Log |
| Filter by tool / action / actor / severity / time | Compliance → Audit Log → toolbar |
| Row detail (expand) | Compliance → Audit Log → click any row |
| Failure drill-down from Action Usage | Compliance → Action Usage → click a non-zero failed-count cell → lands here pre-filtered |
| Failure drill-down from Throughput threshold breach | Slack alert deep-link → lands here pre-filtered to the breaching row |
Related
- Compliance — the umbrella surface; audit log is layer 1
- Data Usage — the per-user volume lens on the same row format
- Action Usage — the per-(tool, action) lens on the same row format
- Notifications — how the operator gets alerted on the kinds of events that show up red
- What flows through, what gets blocked, what gets logged — the editorial argument behind this design