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:
{
"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
| Action | Triggered When |
|---|---|
user.created | A new user signs up or is created by an admin |
user.updated | A user profile is updated |
user.deleted | A user account is deleted |
user.banned | A user account is banned |
user.unbanned | A user account is unbanned |
user.impersonated | An admin impersonates a user |
Session Events
| Action | Triggered When |
|---|---|
session.created | A user signs in and a new session starts |
session.revoked | A user signs out or an admin revokes a session |
session.refreshed | A session token is refreshed |
Email & Password Events
| Action | Triggered When |
|---|---|
email.verified | A user verifies their email address |
email.changed | A user changes their email address |
password.changed | A user changes their password |
password.reset | A password reset is completed |
password.reset_requested | A password reset is requested |
Organization Events
| Action | Triggered When |
|---|---|
organization.created | A new organization is created |
organization.updated | Organization details are updated |
organization.deleted | An organization is deleted |
member.added | A member joins an organization |
member.removed | A member is removed from an organization |
member.role_updated | A member's role is changed |
invitation.created | An invitation is sent |
invitation.accepted | An invitation is accepted |
invitation.revoked | An invitation is cancelled |
Security Events
| Action | Triggered When |
|---|---|
two_factor.enabled | A user enables multi-factor authentication |
two_factor.disabled | A user disables multi-factor authentication |
api_key.created | An API key is generated |
api_key.revoked | An API key is revoked |
sso_connection.created | An SSO connection is added |
webhook.created | A webhook endpoint is added |
webhook.deleted | A webhook endpoint is removed |
Querying Audit Logs via the SDK
Use auditLogs.listEvents to search and filter your audit trail programmatically.
Basic Queries
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.
// 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
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:
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.
// 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.
{
"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 events —
session.createdandsession.revokedtrack every sign-in and sign-out. - Access control changes —
member.role_updatedrecords every role assignment and permission change. - Account lifecycle —
user.created,user.deleted, anduser.bannedtrack 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 monitoring —
session.createdrecords 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 tracking —
user.deletedrecords 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
- 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.
- 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.
- Monitor for anomalies. Use webhooks to get real-time notifications for suspicious patterns — multiple failed sign-ins, mass deletions, or unexpected role escalations.
- Archive old logs externally. For high-volume deployments, periodically export and archive older audit logs to external storage to keep your primary database lean.
- Never disable audit logging. Audit logs are always on for a reason. Compliance frameworks require continuous, uninterrupted logging with no gaps.