Read and export the audit log
Every gateway call is written to the audit log with the redacted payload, the redacted-keys list, the latency, the status, and the correlation ID. This guide is how to read it, filter it, export it, and produce the regulator-specific CSVs the NDPC, CBN, and FIRS will ask for.
~9 min read
What is logged on every call
Every tool call writes a row into gateway_logs with the following columns. Every column is queryable via Supabase's RLS-scoped client; the audit page reads exactly this shape.
timestamp: when the call landed at the gateway, in UTC. The audit page renders it in your browser locale.correlation_id: a UUID that links the gateway- side log row to any downstream events (the HITL pending row, the partner MCP server's own logs if it logs back).user_id: the authenticated user who triggered the call (the operator running the agent), nullable if the call came from an unattended client.client_id: a stable identifier for the calling AI client (e.g.,claude-desktop,console-sandbox).mcp_server_id: the MCP server the call routed to. Nullable for cancelled calls that never reached a server.tool_name: the specific tool invoked.method: the MCP method shape (typicallytools/call).payload_redacted: the request payload after the redactor scrubbed any field name in the Tool Group'spii_mask_keyslist. The original payload is not stored.redacted_keys: an array of field names that were scrubbed. Useful for compliance counters.latency_ms: total gateway-to-response latency. Zero on HITL-pending rows; populated on resolution.status:success,error,pending, orhitl_pending. The HITL state transitions reuse the same row.is_redacted: boolean shortcut forredacted_keys.length > 0. Indexed.error_message: present on error rows;Cancelled by useron HITL cancellations.
The live stream
/console/audit subscribes to gateway_logs through Supabase Realtime and prepends new rows as they land. The header shows a green pulsing dot when the subscription is open; if it ever flips to grey, the page is showing the last-fetched state but new rows are not arriving live (reload to reconnect).
The stream is capped at 200 rows on the client to keep the page responsive; the filtered view re-fetches up to 100 rows from the server when a filter changes, then takes over from there.
RLS guarantees the stream is org-isolated: a user in organisation A never receives a row from organisation B, either on initial fetch or on realtime delta. The Supabase Realtime publication on gateway_logs respects the same row-level policies the table itself defines.
The filter strip
The filters live above the stream. URL-driven, so a filtered view is shareable; refreshing the page preserves the filter. Five controls:
- From and To (date pickers): inclusive range on
timestamp. Submission normalises to UTC ISO strings before the URL update. - Server: dropdown of every server registered in your organisation. "All servers" clears the filter.
- Status: success / error / pending / hitl-pending. "All statuses" clears the filter.
- Redacted only: checkbox; restricts to rows where
is_redacted = true. Useful for compliance spot-checks.
The Apply filters button drives the URL push; the Clear button resets everything. The realtime subscription is keyed on the serialised filter, so changing a filter remounts the stream and re-subscribes; new rows that match the filter still arrive live.
CSV export
The Export CSV button on the filter strip is a link to /api/console/audit-export with the same query string as the on-screen view. The endpoint streams the matching rows in 1,000-row chunks under RLS, so even a 90-day, all-servers export drains to a single CSV without tripping a Supabase row-limit.
Columns mirror the table shape from §1. The filename includes a UTC timestamp so successive exports do not collide on disk.
The endpoint guards access by role: requireRole(["admin", "compliance", "developer", "customer_service", "auditor"]); the member role gets a 403. Per the RBAC matrix, member is the only role without audit access.
Per-server detail view
From /console/servers/[id], scroll to the Recent activity section. It surfaces the most recent calls scoped to that one server, useful when you are diagnosing an outage or a config issue. The same row shape; the difference is purely the filter.
Each server page also shows the registered Tools, the verification status, and a Test this server link that drops into the sandbox at /console/servers/[id]/test with the right serverId pre-filled.
Pre-built regulator reports
The Compliance Centre at /console/compliance includes a Regulator Reports card that downloads pre-built CSVs from /api/console/reports/{ndpc|cbn|firs}. Each report carries a header block (organisation, period, generated timestamp), then one section per data area. The period defaults to the trailing 30 days and is configurable via since and until query parameters.
- NDPC: full NDPA compliance posture. Registration, redactions by PII type, consent register, cross-border transfer log, breach reports.
- CBN: per-server activity. Total calls, success, error, hitl_pending, redacted, average latency.
- FIRS: per-tool transaction summary. Calls per (server, tool) pair, success rates, designed for FIRS tax-reporting cycles.
All three endpoints share the same Bearer-token guard pattern as the audit export, but the role gate is tighter: requireRole(["admin", "compliance", "auditor"]). Developer and customer_service do not see regulator reports even though they can read the audit log directly.
Retention is per Tool Group, not per audit row
A common question from new operators: "how long will my rows stay?". The answer lives on the Tool Group, not on the audit log itself. Each gateway_logs row inherits the audit_retention_days from the Tool Group that owned the tool. The default is 365 days; reads of the log beyond that window return empty.
To extend retention for a particular group, edit the policy and re-save. The change applies prospectively; rows already pruned do not come back.
Where to go from here
- Configure a Tool Group policy covers the retention setting, the role gates, and the PII mask list that shape what the audit log shows.
- The sub-processor disclosure page documents the third parties that see redacted audit data (Supabase, Sentry, PostHog) and what NDPA role each holds.
- The API reference shows the Gateway Sync endpoint that lets a partner MCP server stay in sync with policy changes without polling the audit log.
Tracent Technologies