Banata

Operate Your Project

Audit Logs

Automatic audit trail for all auth events with custom event support, filtering, and export capabilities.

Banata automatically records over 30 authentication events into a structured audit trail. Every sign-in, user creation, role change, and organization update is captured with full context — who did it, what changed, and when it happened.

Audit logs are always on. There is nothing to configure and nothing to enable. They work out of the box so you can focus on building your product while Banata handles the compliance, security monitoring, and debugging trail behind the scenes.


Audit Event Structure

Every audit event captures five pieces of information:

  • Action — what happened (e.g., user.created, session.revoked)
  • Actor — who performed the action, including their type (user, admin, system, or API key), ID, email, IP address, and user agent
  • Target — what was affected, such as a user, organization, session, or invitation
  • Context — additional metadata like the organization ID, request ID, or geographic location
  • Changes — for update events, a before-and-after snapshot of exactly what changed

Here is what a typical audit event looks like:

json
{
  "id": "aud_01HXYZ...",
  "action": "member.role_updated",
  "timestamp": "2025-06-15T14:32:00.000Z",
  "actor": {
    "type": "admin",
    "id": "usr_01ADMIN...",
    "email": "admin@acme.com",
    "ipAddress": "203.0.113.42"
  },
  "target": {
    "type": "member",
    "id": "mbr_01HXYZ...",
    "email": "jane@acme.com"
  },
  "context": {
    "organizationId": "org_01HXYZ..."
  },
  "changes": {
    "before": { "role": "member" },
    "after": { "role": "admin" }
  }
}

Auto-Tracked Events

Banata tracks 30 events automatically, grouped into five categories.

User Events

ActionTriggered When
user.createdA new user signs up or is created by an admin
user.updatedA user profile is updated
user.deletedA user account is deleted
user.bannedA user account is banned
user.unbannedA user account is unbanned
user.impersonatedAn admin impersonates a user

Session Events

ActionTriggered When
session.createdA user signs in and a new session starts
session.revokedA user signs out or an admin revokes a session
session.refreshedA session token is refreshed

Email & Password Events

ActionTriggered When
email.verifiedA user verifies their email address
email.changedA user changes their email address
password.changedA user changes their password
password.resetA password reset is completed
password.reset_requestedA password reset is requested

Organization Events

ActionTriggered When
organization.createdA new organization is created
organization.updatedOrganization details are updated
organization.deletedAn organization is deleted
member.addedA member joins an organization
member.removedA member is removed from an organization
member.role_updatedA member's role is changed
invitation.createdAn invitation is sent
invitation.acceptedAn invitation is accepted
invitation.revokedAn invitation is cancelled

Security Events

ActionTriggered When
two_factor.enabledA user enables multi-factor authentication
two_factor.disabledA user disables multi-factor authentication
api_key.createdAn API key is generated
api_key.revokedAn API key is revoked
sso_connection.createdAn SSO connection is added
webhook.createdA webhook endpoint is added
webhook.deletedA webhook endpoint is removed

Querying Audit Logs via the SDK

Use auditLogs.listEvents to search and filter your audit trail programmatically.

Basic Queries

typescript
import { BanataAuth } from "@banata-auth/sdk";
 
const banata = new BanataAuth({
  apiKey: "your-api-key",
  baseUrl: "https://auth.banata.dev",
});
 
// Get the 50 most recent events
const { data: events, listMetadata } = await banata.auditLogs.listEvents({
  limit: 50,
});
 
// Filter by action — find all sign-ins
const signIns = await banata.auditLogs.listEvents({
  action: "session.created",
  limit: 100,
});
 
// Filter by actor — see everything a specific user did
const userActions = await banata.auditLogs.listEvents({
  actorId: "usr_01HXYZ...",
  limit: 50,
});
 
// Filter by organization — audit a single workspace
const orgEvents = await banata.auditLogs.listEvents({
  organizationId: "org_01HXYZ...",
  limit: 50,
});

Pagination

Audit logs use cursor-based pagination. The listMetadata object returned with each response contains the cursors you need to move forward and backward through results.

typescript
// First page
const page1 = await banata.auditLogs.listEvents({ limit: 20 });
 
// Next page
const page2 = await banata.auditLogs.listEvents({
  limit: 20,
  cursor: page1.listMetadata.after,
});
 
// Previous page
const prevPage = await banata.auditLogs.listEvents({
  limit: 20,
  cursor: page1.listMetadata.before,
});

Querying via the Dashboard

You can also browse your audit trail in the Banata dashboard. Navigate to Audit Logs in the sidebar to see a searchable, filterable view of all events. The dashboard lets you filter by action type, actor, organization, and date range without writing any code.


Custom Audit Events

The 30 auto-tracked events cover authentication and authorization. For business-specific actions — like exporting a document, approving a request, or changing a billing plan — you can log custom events through the SDK.

Via the SDK

typescript
await banata.auditLogs.createEvent({
  action: "document.exported",
  actor: {
    type: "user",
    id: "usr_01HXYZ...",
    email: "user@example.com",
  },
  target: {
    type: "document",
    id: "doc_01HXYZ...",
    name: "Q4 Report",
  },
  context: {
    organizationId: "org_01HXYZ...",
    format: "pdf",
    pageCount: 42,
  },
});

Via the logAuditEvent Helper (Server-Side)

Inside Convex functions, you can log audit events directly using the logAuditEvent helper:

typescript
import { logAuditEvent } from "@banata-auth/convex";
 
// Inside a Convex mutation or action
await logAuditEvent(ctx, {
  action: "report.generated",
  actor: { type: "system", id: "system" },
  target: { type: "report", id: reportId },
  context: { type: "monthly", month: "2025-01" },
});

Custom events appear alongside auto-tracked events in the dashboard and SDK queries, so you get a single unified audit trail for your entire application.


Exporting Audit Logs

You can export audit logs for compliance reporting, external analysis, or long-term archival.

typescript
// Export all events for a date range
const exportData = await banata.auditLogs.exportEvents({
  startDate: "2025-01-01T00:00:00.000Z",
  endDate: "2025-01-31T23:59:59.999Z",
  format: "json",
});
 
// Export only specific event types
const securityExport = await banata.auditLogs.exportEvents({
  startDate: "2025-01-01T00:00:00.000Z",
  endDate: "2025-01-31T23:59:59.999Z",
  actions: ["session.created", "password.reset", "two_factor.enabled"],
  format: "json",
});

Change Tracking

For any update event, Banata captures a before-and-after snapshot so you can see exactly what changed. This is especially useful for investigating permission escalations, profile modifications, and configuration changes.

json
{
  "action": "user.updated",
  "actor": {
    "type": "admin",
    "id": "usr_01ADMIN...",
    "email": "admin@acme.com"
  },
  "target": {
    "type": "user",
    "id": "usr_01HXYZ...",
    "email": "jane@acme.com"
  },
  "changes": {
    "before": {
      "name": "Jane Doe",
      "role": "member"
    },
    "after": {
      "name": "Jane Smith",
      "role": "admin"
    }
  }
}

When reviewing an event like this, you can immediately answer "who changed what, and what was it before?" — no guesswork required.


Compliance Use Cases

SOC 2

SOC 2 requires logging of user authentication events, access control changes, and account lifecycle events. Banata covers these automatically:

  • Authentication eventssession.created and session.revoked track every sign-in and sign-out.
  • Access control changesmember.role_updated records every role assignment and permission change.
  • Account lifecycleuser.created, user.deleted, and user.banned track the full lifecycle of every user account.

HIPAA

HIPAA requires audit trails for access to electronic health information, login monitoring, and access control audits. Banata provides:

  • Login monitoringsession.created records every authentication attempt with IP address and user agent.
  • Access control audits — Organization and role-based access events are tracked automatically.
  • PHI access tracking — Use custom events to log access to protected health information specific to your application.

GDPR

GDPR requires records of processing activities, account deletion tracking, and consent management. Banata helps with:

  • Account deletion trackinguser.deleted records when and by whom an account was removed.
  • Data processing records — Use custom events to log data processing activities relevant to your application.
  • Consent changes — Use custom events to record consent grants and withdrawals alongside your auth audit trail.

Best Practices

  1. Supplement with custom events. The 30 auto-tracked events cover authentication and authorization. Add custom events for business-critical actions like data exports, billing changes, and approval workflows.
  2. Set up a regular export schedule. Keep offline copies of your audit logs for disaster recovery and legal hold requirements. Monthly exports are a good starting point.
  3. Monitor for anomalies. Use webhooks to get real-time notifications for suspicious patterns — multiple failed sign-ins, mass deletions, or unexpected role escalations.
  4. Archive old logs externally. For high-volume deployments, periodically export and archive older audit logs to external storage to keep your primary database lean.
  5. Never disable audit logging. Audit logs are always on for a reason. Compliance frameworks require continuous, uninterrupted logging with no gaps.

Next Steps

  • Webhooks — Get real-time notifications when audit events occur
  • API Keys — Manage programmatic access to your project
  • Deploy — Take your project to production with audit log monitoring in place