Audit trail
What the audit feature records, the JSONL format, the fail-closed startup policy, and how write failures surface
One JSON line per auditable operation, in a local file your log shipper
already watches. Offline by design. Needs the audit license feature; without
it nothing is written: Licensing.

What it records
DBTrail never executes SQL against your databases, so an event is either historical data access (query, time-travel read, reconstruct) or recovery script generation.
- CLI:
query,recover,recover-cascade,reconstruct,verify --explain - MCP tools, the time-travel shim, and the web console, including its RBAC denials
- Out of scope: metadata-only reads and the capture plane
Where it writes
$DBTRAIL_AUDIT_LOG, else /var/log/dbtrail/audit.jsonl. Parent directories
are created; the file is append-only, mode 0600, one unbuffered write per
record.
export DBTRAIL_AUDIT_LOG=/var/log/myco/dbtrail-audit.jsonlThe JSONL format
Field names are capitalized: Time (UTC, RFC 3339), Surface (cli, mcp,
shim, console), Actor (os:<user>, plus profile:<name> when a profile
is active; network surfaces record the authenticated user), Action,
Schema, Table, Detail.
{"Time":"2026-07-16T14:03:22.481Z","Surface":"cli","Action":"query.run","Actor":"os:alice","Schema":"shop","Table":"orders","Detail":{"results":"12","format":"table"}}
{"Time":"2026-07-16T14:05:01.902Z","Surface":"cli","Action":"recover.generate","Actor":"os:alice profile:auditor","Schema":"shop","Table":"orders","Detail":{"statements":"3","dry_run":"false","output":"undo.sql","gtid":""}}jq -r 'select(.Action=="recover.generate") | "\(.Time) \(.Actor) \(.Schema).\(.Table)"' \
/var/log/dbtrail/audit.jsonlFail-closed policy
The gate
License enabled (valid or grace) and claiming audit and the
sink cannot open at startup: dbtrail-ee exits 1 instead of running
unaudited. An expired or disabled audit license never trips it.
- Escape hatch:
DBTRAIL_AUDIT_OPTIONAL=1turns the exit into a warning and runs without the trail. - Still allowed with a dead sink, so you can diagnose it: bare
dbtrail-ee,-h,--help,-v,--version, and thelicense,helpandcompletionsubcommands. Everything else fails closed.
error: audit trail could not be initialized: <reason>
this license includes the "audit" feature; refusing to run unaudited (fail closed).
Fix the audit log destination (DBTRAIL_AUDIT_LOG, default /var/log/dbtrail/audit.jsonl) or set DBTRAIL_AUDIT_OPTIONAL=1 to run without the audit trail.Write failures at runtime
A write that fails after startup (disk full, directory rotated away) never
blocks or crashes the operation: a recovery must finish. The record is lost
for good, and an audit: write failed warning prints at most once every 30
seconds with lost_since_last_warning. Treat it as an incident.
When an audit license lapses
A license claiming audit that is not enabled (expired, updates-lapsed,
invalid, too-new schema) prints an audit trail DISABLED line on every start,
on top of the license banner. Its remedy follows the cause: upgrade dbtrail-ee,
run a release inside the updates window, or renew.
Expiry, grace, and the updates window.