Skip to main content
Tracent TechnologiesTracent Technologies
Get started
All guides

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 (typically tools/call).
  • payload_redacted: the request payload after the redactor scrubbed any field name in the Tool Group's pii_mask_keys list. 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, or hitl_pending. The HITL state transitions reuse the same row.
  • is_redacted: boolean shortcut for redacted_keys.length > 0. Indexed.
  • error_message: present on error rows; Cancelled by user on 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.