Skip to main content

Workspace audit logs

Query Bex workspace audit records, follow pagination, interpret callers and outcomes, and investigate changes without confusing audit events with runtime success.

Share
Last updated on September 23, 2026
On this page

Audit logs help a workspace administrator investigate who requested an operation and which resource it concerned. They complement application logs, deployment status, and notification delivery history. They are not application output or a complete record of every runtime event.

Access and availability

Use a workspace-admin account or an appropriately authorized credential for that workspace. Knowing another workspace's ID does not grant access to its audit history. The API requires configured control-plane storage (BEX_CP_DB_URI); an unavailable audit store returns 503. A caller without workspace management access receives 403.

For the example below, use an admin user's authorized OAuth access token as BEX_TOKEN and set WORKSPACE_ID to the returned workspace ID. Machine API keys have the developer role and cannot read audit history. See the API permission model. Audit records use the owner-scoped route.

Query a time window

Set START_TIME and END_TIME to RFC 3339 timestamps for the incident window, including a timezone, for example 2026-09-05T10:00:00Z:

bash
curl --fail-with-body --silent --show-error --get \
  "$BEX_API_URL/v1/owners/$WORKSPACE_ID/audit-logs" \
  -H "Authorization: Bearer $BEX_TOKEN" \
  --data-urlencode "startTime=$START_TIME" \
  --data-urlencode "endTime=$END_TIME" \
  --data-urlencode 'direction=backward' \
  --data-urlencode 'limit=50'

backward returns newest records first; forward returns oldest first. Omitted direction defaults to newest first. Invalid time or direction values are errors, not requests for an unfiltered history.

The response is an array of {auditLog, cursor} entries. To continue, pass the last returned cursor as cursor and preserve the same time window and direction. Continue until no further entries are returned.

The REST query supports time bounds, direction, cursor, and limit. If you need to narrow by actor, resource, or event, filter the returned records in your analysis.

Interpret a record

FieldMeaning in Bex
id, timestampRecord identity and event time; timestamps are returned in UTC.
eventA mapped Render-style event name where supported, otherwise a Bex operation name.
statussuccess for an allowed audit outcome, or error for a denied outcome.
actorCaller type and, when available, its subject ID. Email is not included.
metadataString-valued details such as the target, changed role, or maintenance setting.
resourceBex's authorization resource reference, when available.

actor.type is user for a browser session, rest_api for an OAuth bearer, or system for other/unattributed callers. A bearer may represent an API key or an OAuth client; inspect available subject and OAuth metadata rather than assuming it identifies a particular human. Missing actor details are not evidence that an operation was harmless.

A denied operation is exposed as status: error with metadata.outcome: denied. Conversely, status: success is not proof that a deployment, job, or database operation finished successfully. Check the resource's resulting state. Event coverage and timing depend on the operation; do not treat the log as an exhaustive transaction journal.

Investigate a change

  1. Record the affected resource ID and an incident window in UTC.
  2. Query and paginate the workspace audit history for that window.
  3. Compare actor, target, event, and available change metadata. For maintenance events, the to value helps distinguish enabling from disabling.
  4. Check the service, deployment, or one-off job state and relevant logs to establish what actually happened.
  5. Apply the appropriate recovery procedure, then verify the application or data result independently of the audit entry.

Keep exported audit data in an access-controlled location. The records omit credential bodies, but caller IDs, resource names, and authorization metadata can still be sensitive.

Retention and missing records

The default retention is 90 days. An installation operator can configure BEX_AUDIT_RETENTION_DAYS; the retention worker purges older records at startup and on its daily sweep. Confirm your installation's retention before relying on historical availability, and export records you need before they expire.

For missing records, check the workspace, time bounds, pagination, permissions, configured store, and retention window. Confirm that the operation emits an audit event; application requests and background activity are not universally audited. Use resource status and runtime logs alongside this history.

Was this page helpful?

Run this on infrastructure you own

bex is the open-source, AI-native Render alternative — push a git repo and get a running HTTPS service on your own machines.

Get started with bex