Repository navigation
2026.10.46
Pre-releaseAdded
-
Say how many events an export will hold (38a51082)
The Export menu names the number of matching events before a format is chosen.
-
Alert when an audit receiver is behind or lost records (623de17a)
A new installation alert condition, AUDIT_DELIVERY, is active for each audit
receiver that has a gap it has not been told about, or whose oldest
unacknowledged record is older than audit.delivery.alert-after. The subject is
the receiver's plugin id and the value is the age of that record. A default
Audit delivery rule is created, enabled and bound to no channel, like the
storage rules, and the condition is offered when editing an installation rule. -
Retention waits for receivers and leaves held records alone (1bb820e2)
The audit purge no longer deletes a record a receiver has not acknowledged until
it is older than audit.delivery.max-unacknowledged-age. When it does delete such
records, the receiver is told with an AuditGap, an AUDIT_GAP audit event records
it, and AuditFeed.retainedFrom reports the time the trail is complete from.A plugin that declares audit.retentionHold provides one AuditRetentionHold
naming time ranges, optionally narrowed by cluster, user, action and target. The
purge leaves every record a hold covers, whatever the retention. It asks before
every batch; a hold that throws, takes longer than audit.delivery.timeout, names
more than 200 entries or belongs to a plugin that is not running on the purging
replica makes the run purge nothing, and the purge status says why. A plugin that
provides an AuditRetentionHold without declaring audit.retentionHold is not
activated. -
Deliver the audit trail to receiver plugins in commit order (4434d00d)
A plugin that declares audit.receive in its manifest provides one AuditReceiver.
Studio calls it with batches of up to 500 records after its cursor, in commit
order, from a job that runs once per installation every two seconds. Returning
from the call acknowledges the batch; throwing or taking longer than
audit.delivery.timeout delivers the same batch again later, after a delay that
doubles from 2 seconds to 5 minutes. Delivery is at least once, so a receiver
identifies a record by its id and position. A receiver never holds up the
audited operation.A new receiver starts at the beginning of the retained trail. Its cursor is
removed when the plugin is uninstalled, not when it is disabled. A plugin that
provides an AuditReceiver without declaring audit.receive is not activated.
When retention removes records a receiver has not acknowledged, the receiver is
told with an AuditGap and an AUDIT_GAP audit event records it.New settings: audit.delivery.max-unacknowledged-age (30d),
audit.delivery.timeout (30s) and audit.delivery.alert-after (1h). -
Add an Export menu to the audit log (8c5bfdb9)
CSV, JSON and NDJSON are plain download links carrying the current filters,
so the browser streams the file to disk and the download can be cancelled.
The button is disabled with its reason without audit:export. -
Export the audit trail as CSV, JSON or NDJSON (a58b48ed)
GET /clusters/{clusterId}/audit/export streams the trail under the same
filters as the list, oldest first, as a file. It needs the new cluster
permission audit:export and holds only what the caller could read in the
list, redacted the same way. CSV cells a spreadsheet would run as a formula
get a leading quote. Each export is itself audited as EXPORT_AUDIT with its
format and filters, and records how far it got if the client cancels. -
Plugins declare audit access in their manifest (de54fa7d)
A plugin.json may carry an audit block with receive and retentionHold flags,
both false by default. The install review lists each flag, the diff shows
flags an update adds or removes, and a plugin that newly declares one is
activated only after the audit-access-added acknowledgement. -
Give every audit record a commit-order position and a feed API (7e46bcb3)
Each audit record now carries a position, the writing transaction's id and a
sequence value stamped by the database. AuditFeed.after returns records in that
order and only once every earlier transaction has ended, so a reader following
the trail never skips a record that commits late. A record whose outcome is
filled in takes a later position, so a reader that already passed it sees the
final state. AuditFeed, AuditRecord and AuditPosition are part of the plugin API.A database guard now keeps the trail honest: only a record's outcome, error,
count and outcome detail can change, only while it is pending (a refusal's count
may keep rising), and nothing else is ever rewritten.
Fixed
-
Delete settled gap rows and fix the tests the audit delivery broke (30474c29)
A gap row is deleted once it is audited and delivered, so the table holds only
open gaps. Tests: the module slices that pull in the data lifecycle mock the
retention guard, the schema baseline and store coverage lists name the new
tables, the audit-access plugin fixture provides the beans it declares, and the
alert rules test no longer depends on the seeded rule order. -
Record a completed second-factor sign-in as a new event (b9f30d2e)
A sign-in finished by its second factor is now a new successful login event
whose parent is the attempt, instead of changing the attempt's outcome. The
attempt's own record stays as it was written. -
Keep gap counts, in-flight calls and export outcomes honest (24e0468a)
A purge writes a new gap row each time instead of adding to one a delivery may
have read, so an acknowledgement cannot mark an unseen count delivered. The
AUDIT_GAP claim reads the row in the same statement, and the claim is given
back only when the event could not be started. A receiver or hold that ignores
its timeout is not called again until it has returned. An export records its
outcome after the sink is flushed and closed. -
Record an audit outcome once and ignore a second one (71dfb2d0)
A row that already has its outcome is no longer overwritten by a later success or
failure for the same operation. The first outcome stands and the second is logged
as a warning, now that the database refuses rewriting a finished audit record.