Audit logging & change data capture#
Mutations are captured to an audit_log table via CockroachDB
change-data-capture (CHANGEFEED) and read back over HTTP. Tracked tables:
devices, racks, crac_units, cables, and fabric_links.
Reading the history#
serve exposes the change history on the HTTP port:
curl -s 'localhost:8081/audit/history?table=racks&limit=50' | jqTwo delivery paths, one destination#
Both paths land each change in audit_log; pick one.
In-process core changefeed (default in k8s, license-free). Set
AUDIT_CHANGEFEED=trueandserveruns anEXPERIMENTAL CHANGEFEEDover its own connection, recording each change. No inbound network needed — ideal for self-hosted/dev. Single-replica only: this feed runs inside every replica, so at more than one replica each mutation is recorded once per replica (duplicateaudit_logrows).servewarns about this at startup. Run it on exactly one replica, or use the webhook sink below.AUDIT_CHANGEFEED=true rackattack serve # ... perform some mutations ... curl -s 'localhost:8081/audit/history?table=racks' | jqNative webhook sink (CockroachDB owns delivery, retries, and checkpointing). Apply
deploy/changefeed.sql, which creates aCHANGEFEED … INTO 'webhook-https://…/audit/webhook'pointing at thePOST /audit/webhooksink. This is the right choice at more than one replica: it’s a single cluster-owned feed regardless of replica count, so each mutation is recorded exactly once. LeaveAUDIT_CHANGEFEEDunset so changes aren’t double-recorded, and authenticate the sink withAUDIT_WEBHOOK_SECRET.
Licensing note#
On CockroachDB v24.3+ (the v26 CCL build used here) the webhook sink runs without an enterprise license key; a long-running production changefeed should still install the free Enterprise license to avoid grace-period throttling. The core-changefeed path needs no license.
The implementation lives in
internal/audit.