Skip to main content

Documentation Index

Fetch the complete documentation index at: https://langwatch.ai/docs/llms.txt

Use this file to discover all available pages before exploring further.

Every gateway-resource mutation (Virtual Key, Budget, Provider Binding, Cache Rule) writes a row to the platform-wide 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 (TypeScript const 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 codeActorTarget
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}sametargetKind=budget / targetId=<budget_id> (deleted is the soft-archive)
gateway.provider_binding.{created, updated, deleted}sametargetKind=provider_binding / targetId=<binding_id>
gateway.cache_rule.{created, updated, deleted}sametargetKind=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.
Reads are not logged — the volume would swamp the ledger without adding governance value. If you need read-access attribution for compliance, use OTel trace logs (every request has langwatch.principal_id).

Viewing in the UI

Go to /settings/audit-log (Enterprise plan, gated on auditLog:view — granted by default to all four TeamUser roles incl. CUSTOM) and use the filters to narrow:
  1. Source badge — purple “Gateway” / grey “Platform” on every row.
  2. Filter by actiongateway.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 the gateway. prefix so a single LIKE 'gateway.%' clause filters the entire gateway surface for SIEM exports.
  3. Filter by Targetvirtual_key / budget / provider_binding / cache_rule. Selecting any value implicitly hides platform rows (which have null targetKind).
  4. Expand with changed-fields diff summary — UPDATE rows expand to show a compact top-level diff (e.g. priority 200 → 300, action.ttl 300 → 600 as red/green code badges) above the raw Before/After JSON panels.
  5. 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.
  6. 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:
  1. 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.
  2. Scripted / scheduled SIEM export — query the Postgres AuditLog table directly from your SIEM ingestion pipeline. Filter on targetKind IN ('virtual_key', 'budget', 'provider_binding', 'cache_rule') to scope to gateway rows; join User on userId for actor enrichment. The schema is documented in langwatch/prisma/schema.prisma → model AuditLog.
  3. 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.
A first-class REST audit-export endpoint is a v1.2 follow-up; until then, the CSV download is the supported export path for governance / compliance use cases.

Retention

Default: 7 years, extendable on request. Stored in the primary app Postgres under AuditLog. 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 dedicated GatewayAuditLog 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 pgaudit extension, 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.