Audit Log Service
A high-performance engine for ingesting and querying structured audit events. Built for multi-tenant SaaS compliance and transparency.
System Overview
The Audit Log service provides an immutable, verifiable record of all critical actions within your application. It supports multi-tenant isolation out of the box, ensuring that Company A can never access logs from Company B.
Structured Logs
Rigid schema for actors, resources, and metadata—no messy text blobs.
Search & Filters
Rich query API with support for severeity levels and categories.
High Volume
Optimized for ingestion peaks via NATS batching and Postgres Copy.
Local Development
# 1. Start Dependencies
docker run --rm -p 5432:5432 -e POSTGRES_PASSWORD=postgres postgres:16
docker run --rm -p 4222:4222 nats:2
# 2. Run Migrations & Start Server
make dev-setup
make runService listens on 8080 for ConnectRPC and 50051 for gRPC.
CLI Inspection
Ingestion Pipeline
High-volume event ingestion is handled via a decoupled architecture using NATS for scale and PostgreSQL for verifiable persistence.
Event Payload Schema
Every audit event is an immutable record. While the server can generate IDs and timestamps, integrators are encouraged to provide client-side occurred_at to account for ingestion delays.
{
"tenant_id": "7e4e4e93-94ec-45bd-87ce-88ce3f689e3c",
"action": "user.login",
"category": "CATEGORY_AUTH",
"severity": "SEVERITY_INFO",
"actor": {
"type": "ACTOR_TYPE_USER",
"id": "user-123",
"display_name": "Jane Doe"
},
"primary_resource": {
"type": "user",
"id": "user-123"
},
"description": "Successful portal login",
"metadata": { "ip": "192.0.2.10" }
}Actors & Resources
Actors (Who?)
The Actor represents the entity triggering the action. Must include a type (USER, SYSTEM, SERVICE, API_KEY).
USER: Interactive human actions.SERVICE: Machine-to-machine calls.
Resources (What?)
ResourceRef identifies the objects impacted. Separate fields for type and ID allow for polymorphic relations.
primary_resource: The main target.related_resources: Ancillary objects.
Capturing Data Changes
For UPDATED actions, it is standard practice to include the delta. The ChangeSet object captures the state before and after.
"changes": {
"old_value": { "role": "editor", "active": true },
"new_value": { "role": "admin", "active": true },
"changed_fields": ["role"]
}Integration Guide
Synchronous Writes
Best for critical operations where knowing the event is persisted is mandatory.
const response = await auditClient.writeEvent({
event: {
tenantId: companyId,
action: "security.password_reset",
severity: Severity.SECURITY,
actor: { id: userId, type: ActorType.USER },
primaryResource: { id: userId, type: "user" }
}
});
console.log('Event registered:', response.eventId);Batch & Asynchronous Ingestion
For high-throughput systems, prefer using the Batch API or publishing to NATS. This service drains the audit.events subject and flushes records to Postgres via CopyFrom.
Filtering & Search
The Query API is optimized for Admin Dashboards. It uses cursor-based pagination to handle millions of records without performance degradation.
# Search for security errors in the last 24h
curl "http://audit-log/v1/audit/events?\
tenant_id=XYZ\
&severities=SEVERITY_SECURITY\
&categories=CATEGORY_AUTH\
&page_size=50"Pagination Strategy
Always store and reuse the next_page_token. Tokens encode micro-second timestamps and UUIDs to ensure stable paging even as new logs are being ingested.
Compliance Ready
The Launch Rail Audit Log service is designed for SOC2 and HIPAA compliance requirements. Every event is cryptographically timestamped and stored in partitioned Postgres tables, allowing for multi-year retention and lightning fast audits.
View Audit API Reference