Skip to content

Audit Logs

Breeze RMM provides three distinct logging systems that together give you full visibility into platform activity, agent health, and device-level events. Each system serves a different purpose and is stored in its own database table with dedicated API endpoints.

Log Types Overview

Log TypePurposeSourceDatabase Table
Platform Audit LogsTrack user, API key, agent, and system actions across the platformAPI serveraudit_logs
Agent Diagnostic LogsCapture internal agent runtime diagnostics (debug, info, warn, error)Breeze agentagent_logs
Device Event LogsCollect OS-level event logs from managed devices (security, hardware, application, system)Managed devicesdevice_event_logs

Platform Audit Logs

Platform audit logs record every significant action taken within your Breeze environment. They are the primary compliance and security trail.

Audit Log Fields

Each audit log entry contains the following fields:

FieldTypeDescription
idUUIDUnique identifier for the log entry
orgIdUUIDOrganization the action belongs to (multi-tenant scoping)
timestampTimestampWhen the action occurred (defaults to current time)
actorTypeEnumWho performed the action: user, api_key, agent, or system
actorIdUUIDIdentifier of the actor (user ID, agent ID, etc.)
actorEmailString (255)Email address of the actor (when available)
actionString (100)The action performed (e.g., user.login, device.create, script.execute)
resourceTypeString (50)Type of resource acted upon (e.g., device, policy, organization)
resourceIdUUIDIdentifier of the affected resource
resourceNameString (255)Human-readable name of the affected resource
detailsJSONBAdditional context about the action (before/after values, parameters, etc.)
ipAddressString (45)Client IP address (supports IPv4 and IPv6)
userAgentTextClient user-agent string
resultEnumOutcome of the action: success, failure, or denied
errorMessageTextError details when the result is failure or denied
checksumString (128)Integrity checksum for tamper detection

Actor Types

Breeze tracks four types of actors:

Actor TypeDescriptionExample Actions
userA human user authenticated via JWTLogging in, updating a device, exporting data
api_keyAn API key (prefix brz_) used for programmatic accessAutomated script execution, integrations
agentA Breeze agent running on a managed deviceSubmitting event logs, heartbeat updates
systemInternal platform operations with no human actorScheduled cleanups, automated policy evaluations

When a non-UUID actor ID is provided (e.g., an agent string identifier), the system stores a zero UUID as the actorId and preserves the original value in the details JSONB field under the key rawActorId. The same treatment applies to non-UUID resourceId values, stored as rawResourceId in details.

Action Categories

Actions are classified into categories based on their prefix. This categorization drives the reporting endpoints:

CategoryAction PrefixesExamples
authenticationuser.login, user.logout, user.permissionuser.login, user.login.failed, user.permission.change
devicedevice.device.create, device.update, device.delete
automationscript.script.execute
policypolicy., automation.policy.policy.create, policy.update, policy.evaluate, automation.policy.evaluate
alertalert.alert.create, alert.acknowledge
compliancedata.data.access, data.export
organizationorganization.organization.update
systemEverything elseSystem-generated events

Security Actions

The following actions are flagged as security events and appear in the security events report:

  • user.login
  • user.login.failed
  • user.permission.change
  • policy.update
  • policy.create
  • policy.evaluate
  • automation.policy.evaluate

Compliance Actions

The following actions are tracked for compliance reporting:

  • data.access
  • data.export
  • device.create, device.delete
  • policy.update, policy.evaluate, automation.policy.evaluate
  • script.execute
  • organization.update

Writing Audit Events

Audit events are written asynchronously via createAuditLogAsync, which inserts into the database without blocking the request. If the insert fails, the error is logged to the console (suppressed in test environments).

Two helper functions are available in application code:

  • writeAuditEvent(c, event) — Low-level function that accepts a request-like context and an AuditEventInput object. Extracts the client IP from X-Forwarded-For and the user-agent from request headers. Events with no orgId are silently dropped (with a console warning in non-test environments).
  • writeRouteAudit(c, event) — Convenience wrapper for route handlers that automatically extracts actorId and actorEmail from the Hono auth context.

Filtering and Searching

The audit log list endpoints support the following query parameters for filtering:

ParameterTypeDescription
pageString (number)Page number (default: 1)
limitString (number)Results per page (default: 50, max: 100)
userStringFilter by actor email or user name (ILIKE match)
actionStringFilter by action name (ILIKE match)
resourceStringFilter by resource type or resource name (ILIKE match)
fromISO 8601 datetimeStart of date range
toISO 8601 datetimeEnd of date range

The search endpoint (GET /search) adds a q parameter that performs a full-text ILIKE search across action, actor email, resource type, resource name, and the JSON-cast details field. Search conditions are combined with any active filters using AND logic.

Retention Policies

Audit log retention is configured per organization in the audit_retention_policies table:

FieldTypeDefaultDescription
retentionDaysInteger365Number of days to retain audit logs
archiveToS3BooleanfalseWhether to archive logs to S3 before deletion
lastCleanupAtTimestampnullWhen the last cleanup ran

Agent Diagnostic Logs

Agent diagnostic logs capture internal runtime information from the Breeze agent running on managed devices. These are useful for troubleshooting agent connectivity, update failures, and component-level issues.

Agent Log Fields

FieldTypeDescription
idUUIDUnique identifier
deviceIdUUIDThe device this agent runs on
orgIdUUIDOrganization scope
timestampTimestampWhen the log entry was generated on the agent
levelEnumSeverity: debug, info, warn, or error
componentString (100)Agent subsystem that generated the log (e.g., updater, heartbeat, ws)
messageTextThe log message
fieldsJSONBStructured key-value metadata attached to the log entry
agentVersionString (50)Version of the agent that generated the entry
createdAtTimestampWhen the record was inserted into the database

Database Indexes

The agent_logs table has the following indexes for efficient querying:

  • agent_logs_device_idx — By device ID
  • agent_logs_org_ts_idx — By organization ID and timestamp (composite)
  • agent_logs_level_component_idx — By level and component (composite)
  • agent_logs_timestamp_idx — By timestamp

Log Ingestion

Agents submit diagnostic logs via POST /agents/:id/logs with a JSON body containing a logs array (maximum 500 entries per request). Each entry must include:

  • timestamp (ISO 8601 datetime)
  • level (debug, info, warn, error)
  • component (string, max 100 characters)
  • message (string)
  • fields (optional object with arbitrary key-value pairs)
  • agentVersion (optional string, max 50 characters)

Logs are batch-inserted in groups of 100 rows. The endpoint returns the number of successfully inserted records.

Querying Diagnostic Logs

Diagnostic logs are queried via GET /devices/:id/diagnostic-logs with the following optional parameters:

ParameterTypeDescription
levelStringFilter by level(s), comma-separated (e.g., warn,error)
componentStringFilter by component name (exact match)
sinceISO 8601 datetimeStart of time range
untilISO 8601 datetimeEnd of time range
searchStringILIKE search on the message field
pageString (number)Page number
limitString (number)Results per page (default max: 1000)

Results are ordered by timestamp descending and include the total count for pagination.


Device Event Logs

Device event logs represent OS-level events collected from managed devices. There are two mechanisms for working with device event logs: stored event logs (persisted in the database) and live event log queries (real-time queries sent to the agent).

Stored Event Logs

Agents periodically submit event logs that are stored in the device_event_logs table for historical querying.

Stored Event Log Fields

FieldTypeDescription
idUUIDUnique identifier
deviceIdUUIDThe device the event came from
orgIdUUIDOrganization scope
timestampTimestampWhen the event occurred on the device
levelEnumSeverity: info, warning, error, or critical
categoryEnumEvent category: security, hardware, application, or system
sourceString (255)The source application or component
eventIdString (100)OS-specific event identifier
messageTextThe event message
detailsJSONBAdditional structured event data
createdAtTimestampWhen the record was inserted

Deduplication

The device_event_logs table has a unique index on (deviceId, source, eventId) to prevent duplicate events. When an agent submits events that conflict with existing records, the duplicates are silently ignored (ON CONFLICT DO NOTHING).

Database Indexes

  • device_event_logs_device_idx — By device ID
  • device_event_logs_org_ts_idx — By organization ID and timestamp (composite)
  • device_event_logs_cat_level_idx — By category and level (composite)
  • device_event_logs_dedup_idx — Unique index on (device ID, source, event ID)

Event Submission

Agents submit event logs via PUT /agents/:id/eventlogs with a JSON body containing an events array. Each event must include:

  • timestamp (string, required)
  • level (info, warning, error, critical)
  • category (security, hardware, application, system)
  • source (string, required)
  • eventId (string, optional)
  • message (string, required)
  • details (optional object)

Events are batch-inserted in groups of 100. The submission is also recorded as an audit event with action agent.eventlogs.submit.

Querying Stored Event Logs

Query stored event logs for a device via GET /devices/:id/eventlogs:

ParameterTypeDescription
categoryEnumFilter by category: security, hardware, application, system
levelEnumFilter by level: info, warning, error, critical
sourceStringFilter by source (exact match)
startDateISO 8601 datetimeStart of time range
endDateISO 8601 datetimeEnd of time range
pageString (number)Page number
limitString (number)Results per page (default max: 500)

Live Event Log Queries

For real-time inspection, Breeze can query the Windows Event Log (or equivalent) directly on a device by sending commands through the agent. These are available under both the /system-tools/ and /devices/ route namespaces.

List Available Event Logs

GET /system-tools/devices/:deviceId/eventlogs

Returns the list of event logs available on the device (e.g., Application, Security, System). Each log includes:

FieldTypeDescription
nameStringInternal log name
displayNameStringHuman-readable display name
recordCountNumberNumber of records in the log
maxSizeNumberMaximum log size in bytes
retentionDaysNumberConfigured retention period
lastWriteTimeStringTimestamp of the most recent entry

Get Event Log Info

GET /system-tools/devices/:deviceId/eventlogs/:name

Returns metadata for a specific event log by name (case-insensitive match).

Query Event Log Entries

GET /system-tools/devices/:deviceId/eventlogs/:name/events
ParameterTypeDescription
pageString (number)Page number
limitString (number)Results per page
levelEnumFilter by level: information, warning, error, critical, verbose
sourceStringFilter by source
startTimeISO 8601 datetimeStart of time range
endTimeISO 8601 datetimeEnd of time range
eventIdString (number)Filter by OS event ID

Each returned event entry contains:

FieldTypeDescription
recordIdNumberRecord identifier within the log
timeCreatedStringWhen the event was generated
levelEnuminformation, warning, error, critical, or verbose
sourceStringSource application or component
eventIdNumberOS-specific event ID
messageStringEvent message text
categoryStringEvent category
userString or nullUser associated with the event
computerStringComputer name
rawXmlStringRaw XML representation (when available)

Get Single Event Record

GET /system-tools/devices/:deviceId/eventlogs/:name/events/:recordId

Returns a single event log entry by its record ID.


API Reference

Platform Audit Log Endpoints

All audit log endpoints are mounted at /api/v1/audit-logs and require JWT authentication.

List Audit Logs (Flat Format)

GET /audit-logs

Returns entries in a flattened format used by the AuditLogViewer UI component. Supports page, limit, user, action, resource, from, and to query parameters.

Response shape:

{
"entries": [
{
"id": "uuid",
"timestamp": "2026-02-18T12:00:00.000Z",
"action": "device.create",
"resource": "My Workstation",
"resourceType": "device",
"details": "{}",
"ipAddress": "192.168.1.10",
"userAgent": "Mozilla/5.0...",
"sessionId": null,
"user": {
"name": "Jane Admin",
"email": "jane@example.com",
"role": "user",
"department": ""
},
"changes": {
"before": {},
"after": {}
}
}
],
"pagination": {
"page": 1,
"limit": 50,
"total": 142,
"totalPages": 3
}
}

List Audit Logs (Full Format)

GET /audit-logs/logs

Returns entries in a detailed format used by RecentActivity and UserActivityReport components. Same query parameters as above.

Response shape:

{
"data": [
{
"id": "uuid",
"timestamp": "2026-02-18T12:00:00.000Z",
"user": {
"id": "uuid",
"name": "Jane Admin",
"email": "jane@example.com",
"role": "user"
},
"action": "device.create",
"resource": {
"type": "device",
"id": "uuid",
"name": "My Workstation"
},
"category": "device",
"result": "success",
"ipAddress": "192.168.1.10",
"userAgent": "Mozilla/5.0...",
"details": {}
}
],
"pagination": { "page": 1, "limit": 50, "total": 142, "totalPages": 3 }
}

Get Single Audit Log

GET /audit-logs/logs/:id

Returns a single audit log entry in full format. Returns 404 if the entry does not exist or belongs to a different organization.

Search Audit Logs

GET /audit-logs/search?q=login

Full-text search across action, actor email, resource type, resource name, and details. The q parameter is required (minimum 1 character). All standard filter parameters (user, action, resource, from, to) can be combined with the search query.

Agent Diagnostic Log Endpoints

Submit Agent Logs

POST /agents/:id/logs

Requires agent bearer token authentication. Accepts a JSON body:

{
"logs": [
{
"timestamp": "2026-02-18T12:00:00Z",
"level": "warn",
"component": "updater",
"message": "Update check failed: connection timeout",
"fields": { "retryCount": 3, "endpoint": "https://updates.example.com" },
"agentVersion": "1.4.2"
}
]
}

Maximum 500 log entries per request. Returns { "received": <count> } with status 201.

Device Event Log Endpoints

Submit Device Event Logs

PUT /agents/:id/eventlogs

Requires agent bearer token authentication.

{
"events": [
{
"timestamp": "2026-02-18T11:45:00Z",
"level": "error",
"category": "application",
"source": "Application Error",
"eventId": "1000",
"message": "Faulting application name: app.exe",
"details": { "faultModule": "ntdll.dll" }
}
]
}

Returns { "success": true, "count": <inserted> }.

Query Stored Event Logs

GET /devices/:id/eventlogs?category=security&level=error&startDate=2026-02-01T00:00:00Z

Requires JWT authentication. Returns paginated results from the device_event_logs table.


Multi-Tenant Scoping

All audit log queries are automatically scoped to the caller’s organization. The orgCondition from the authenticated user’s context is applied to every database query, ensuring that users can only see audit logs for their own organization. Partner-scoped users may see logs across their managed organizations.


Troubleshooting

Audit events are not being recorded

  1. Verify that the action handler calls writeAuditEvent() or writeRouteAudit(). Events are written asynchronously, so failures do not block request handling.
  2. Check the API server console for [audit] Failed to write audit log: messages, which indicate database insert failures.
  3. Confirm the orgId is being passed. Events with a null or undefined orgId are silently dropped. Look for [audit] Dropped event (no orgId): warnings in the console.
  4. Ensure the actorType value is one of the four valid enum values: user, api_key, agent, or system.

Agent diagnostic logs are not appearing

  1. Confirm the agent is shipping logs by checking the response from POST /agents/:id/logs. A 201 with { "received": N } indicates the API accepted the batch.
  2. Verify the agent ID maps to a valid device. The endpoint looks up the device by agentId and returns 404 if no match is found.
  3. Check batch insert errors in the API console: [AgentLogs] Error batch inserting logs for device <id>.
  4. Ensure each log entry has valid level, component, and timestamp fields matching the expected schema.

Device event logs return empty results

  1. For stored events, confirm the agent has submitted events via PUT /agents/:id/eventlogs. Check the count in the response.
  2. For live queries, verify the device is online and connected to the WebSocket. Live queries have a 30-second timeout.
  3. Check that your query filters (category, level, source, date range) are not too restrictive. Try removing filters to get unfiltered results first.
  4. For deduplication issues, note that the device_event_logs table has a unique index on (deviceId, source, eventId). If the same event is submitted again, it is silently skipped.

Export returns no data

  1. Verify your filters and date range are correct. The export endpoints apply the same filtering logic as the list endpoints.
  2. Check that the organization has audit log entries in the specified time range.
  3. Note that exports are capped at 10,000 rows. If you need more, narrow the date range or filter criteria and export in batches.

Live event log queries time out

  1. Confirm the target device is online and the agent is connected.
  2. The command timeout is 30 seconds. Large event logs on the device may exceed this timeout.
  3. Use the level, source, and eventId filters to narrow the query and reduce response size.
  4. Check the API console for Failed to parse agent response for event messages, which may indicate the agent returned an unexpected format.