Every gateway-resource mutation (Virtual Key, Budget, Provider Binding, Cache Rule) writes a row to the platform-wideDocumentation Index
Fetch the complete documentation index at: https://langwatch.ai/docs/llms.txt
Use this file to discover all available pages before exploring further.
AuditLog table. There is no separate gateway-only audit table — gateway events live alongside org-level platform events (member changes, settings, RBAC, billing) in /settings/audit-log, with a Source badge distinguishing the two.
One audit log, two write shapes. Gateway-shape rows carry
targetKind / targetId / before / after. Platform-shape rows carry args / metadata / error. The viewer renders both with the same row template, computes source from the presence of targetKind, and offers a target-kind filter for narrowing to gateway events only.What’s logged
Action codes for gateway mutations (TypeScriptconst union in langwatch/src/server/gateway/auditLog.repository.ts):
Action codes use a gateway.<resource>.<verb> dotted-lowercase shape, parallel to platform-side codes (organization.member.add, project.update). Verbs are past-tense to match Stripe / GitHub / Slack / Datadog audit conventions.
| Action code | Actor | Target |
|---|---|---|
gateway.virtual_key.{created, updated, rotated, revoked, deleted} | resolved user (session, PAT, or API token mapped to a user) | targetKind=virtual_key / targetId=<vk_id> |
gateway.budget.{created, updated, deleted} | same | targetKind=budget / targetId=<budget_id> (deleted is the soft-archive) |
gateway.provider_binding.{created, updated, deleted} | same | targetKind=provider_binding / targetId=<binding_id> |
gateway.cache_rule.{created, updated, deleted} | same | targetKind=cache_rule / targetId=<rule_id> |
Guardrail attach/detach events are NOT recorded as standalone audit rows — guardrail configuration changes flow through
gateway.virtual_key.updated (the guardrail list is a field on VirtualKey.config). Standalone gateway.guardrail.{attached, detached} actions are a v1.1 follow-up if operators want finer-grained audit.langwatch.principal_id).
Viewing in the UI
Go to /settings/audit-log (Enterprise plan, gated onauditLog:view — granted by default to all four TeamUser roles incl. CUSTOM) and use the filters to narrow:
- Source badge — purple “Gateway” / grey “Platform” on every row.
- Filter by action —
gateway.virtual_key.created,gateway.virtual_key.rotated, etc. for gateway rows; platform rows use the same dotted style (e.g.organization.member.add,project.update). All gateway codes share thegateway.prefix so a singleLIKE 'gateway.%'clause filters the entire gateway surface for SIEM exports. - Filter by Target —
virtual_key/budget/provider_binding/cache_rule. Selecting any value implicitly hides platform rows (which have null targetKind). - Expand with changed-fields diff summary — UPDATE rows expand to show a compact top-level diff (e.g.
priority 200 → 300,action.ttl 300 → 600as red/green code badges) above the raw Before/After JSON panels. - CREATE/DELETE events show the full field list — since those events have a null Before (or null After), the diff summary renders the relevant half as a field list instead of leaving the panel blank for the most common audit event class.
- Deep-link IN from resource detail pages — every VK detail and budget detail page carries an Audit history button that takes you to
/settings/audit-log?targetKind=<kind>&targetId=<id>with a pre-filled filter chip scoped to just that resource. Clear the chip with the×icon to re-expand the view. The pattern stays reachable on revoked VKs and archived budgets so forensic investigations start from the current state, not some “active only” fork.
Querying programmatically
There is no public REST endpoint for audit log retrieval — gateway audit reads share the same tRPC procedure (organization.getAuditLogs) that powers /settings/audit-log. Three paths, ranked by typical operator use case:
- One-off / human review — open
/settings/audit-log, set the filters you want (Source, Action, Target), then hit Export CSV to download the filtered rows. The CSV carries gateway-shape fields (targetKind,targetId,before,after) for gateway rows and platform-shape fields (args,metadata) for platform rows. - Scripted / scheduled SIEM export — query the Postgres
AuditLogtable directly from your SIEM ingestion pipeline. Filter ontargetKind IN ('virtual_key', 'budget', 'provider_binding', 'cache_rule')to scope to gateway rows; joinUseronuserIdfor actor enrichment. The schema is documented inlangwatch/prisma/schema.prisma → model AuditLog. - In-app integrations — call the tRPC procedure from a TypeScript client that already has a session:
await trpc.organization.getAuditLogs.query({ organizationId, targetKind, targetId, since, limit }). Mirrors what the UI does. Not intended for cross-network REST consumers.
Retention
Default: 7 years, extendable on request. Stored in the primary app Postgres underAuditLog. The table is indexed on (organizationId, createdAt) and (targetKind, targetId) to keep both org-tail queries and per-resource queries fast.
Migration note (v3.1)
Earlier v3.0 builds wrote gateway audit rows to a dedicatedGatewayAuditLog table with a GatewayAuditAction Postgres enum. The consolidation migration 20260425000000_consolidate_gateway_audit_into_audit_log extends AuditLog with targetKind / targetId / before / after columns and drops the gateway-only table. Self-hosters upgrading from v3.0 should run pending Prisma migrations on app boot per the standard upgrade procedure — the gateway audit log table goes away and downstream gateway services start writing to AuditLog directly. Per the v3.0 release note no audit rows were retained.
Security considerations
- Can the audit log be tampered with? Writes are append-only at the service layer — no UPDATE or DELETE is exposed. Deletions are only possible via direct database access, which is control-plane-operator-only and also audit-logged (via Postgres’ built-in
pgauditextension, configured in the self-hosted deployment guide). - Can an audit entry be forged? No. Gateway writes happen inside the same transaction as the resource mutation; either both land or neither lands. A caller cannot emit a fake audit entry via REST or CLI.
- Notifications on security-sensitive writes. Rotations and revocations generate an organization-wide notification by default (configurable per org).
See also
- Security — how audit fits into the broader governance story.
- RBAC — who can view the unified audit log.
- Virtual Keys → Rotation — the operation that makes auditability load-bearing.