Skip to main content

Where the rows live

Gateway mutations write to the same AuditLog table as the rest of the platform. Open Settings, Audit Log to read them. Gateway rows carry a purple Gateway badge; platform rows, such as a member change or a project edit, carry a grey Platform badge. A gateway row records the actor, the action code, the target kind, the target id, and the before and after state of the row that changed. On a virtual-key row, both halves leave the hashed secret out. The actor is the user who made the change. A write that arrives on a legacy project API key, which carries no user, records the machine actor svc_<projectId>.

What is logged

Action codes read gateway.<resource>.<verb>, with the verb in the past tense. Each row is written inside the same database transaction as the change it records, so a change either lands with its audit row or does not land at all. Revoking a virtual key also archives the budgets scoped to that key, so a revocation writes a gateway.virtual_key.revoked row and one gateway.budget.deleted row per archived budget.
Attaching or detaching a guardrail writes two rows. The guardrail list is a field on the key, so the edit itself produces gateway.virtual_key.updated, and each added or removed guardrail produces its own gateway.virtual_key.guardrail_attached or gateway.virtual_key.guardrail_detached row carrying the guardrail id and its direction.
Reads are not logged. For read attribution, use the trace on each request, which carries the virtual key that made the call. See Observability.

Reading the log in the app

The Audit Log page is at Settings, Audit Log. It needs the auditLog:view permission at the organization and the Enterprise plan. Filter by user name or email, by action code, by project, and by date range. All gateway codes start with gateway., so typing gateway. in the action filter narrows the page to gateway rows. Every virtual key and every budget detail page has an Audit history button. It opens the Audit Log page filtered to that resource, and the filter shows as a chip you can clear. The button stays available on a revoked key and on an archived budget, so a forensic review starts from the resource itself.

Querying programmatically

Export CSV on the Audit Log page downloads the rows the current filters select. The file carries these columns: Args, Before and After are JSON, capped at 4096 characters per cell. A capped cell ends with a …[truncated N chars] marker. For a scheduled export into a SIEM, call the same query the Audit Log page uses: organization.getAuditLogs, at GET /api/trpc/organization.getAuditLogs with the input JSON in the input query parameter. It takes an organizationId, optional projectId, userId, action and startDate/endDate filters, and pages with pageOffset and pageSize up to 10000. It checks auditLog:view at the organization every call, so the export carries the same authorization as the page. There is no REST endpoint for audit rows. Reading the AuditLog table in the application Postgres database is possible on a self-hosted deployment that owns the database, and it enforces no permission of its own, so keep it for operators who already hold database credentials. Filter on organizationId first, because that column is what separates one organization’s rows from another’s, then on targetKind IN ('virtual_key', 'budget', 'cache_rule', 'guardrail') for gateway rows, and join User on userId for the actor. For a governance event feed, see OCSF export, which carries trace and anomaly events rather than these audit rows.

Retention and integrity

Rows live in the application Postgres database, indexed on (organizationId, createdAt) and on (targetKind, targetId), which is what keeps both the organization-wide view and the per-resource view fast. The application only ever inserts into this table. It exposes no update and no delete path, so a row that lands stays as written. Also check: Virtual Keys for the rotation and revocation operations behind those action codes, RBAC for who can read the log, Security for the rest of the security boundary.
Last modified on September 6, 2026