Skip to content

Audit log

A signed, tamper-evident log of approvals, guard blocks and redactions, budget stops, memory deletes and exports. Guide: Audit log.

Audit export: a signed, tamper-evident log of approvals, budgets, guards, memory and more.

AuditRecord = dict[str, Any] module-attribute

KEY_ENV = 'AA_AUDIT_KEY' module-attribute

AuditEntry dataclass

One security-relevant fact, before it is signed: what, when, which run and call.

body()

The unsigned record of this entry.

AuditSink

Queues security-relevant events for store on a writer thread; ignores all others.

Raises:

Type Description
ConfigError

store is not an AuditStore, or a bad max_queue.

healthy property

True while no record was lost.

flush(timeout=5.0)

Wait until every queued record is stored; False on timeout.

require()

Strict mode: wait until queued records are stored; raise if any was lost.

settled()

True when require would return at once: lenient, stopped, or nothing queued.

stop(timeout=10.0)

Detach, store the queue, then seal; a failure is logged and counted, not raised.

AuditStore

Bases: Protocol

Keeps audit entries signed and in order.

close()

Seal what was written; later writes are refused.

digest(value)

A keyed digest of value (a scope, edited arguments): linkable, not reversible.

write(entry)

Sign and keep one entry; raises on failure (the sink logs it).

AuditUnavailable

Bases: AdapterError

A fail-closed audit log lost a record (or could not store it in time); no call runs.

AuditVerification dataclass

The result of verify: ok only when nothing at all is wrong.

anchor property

log_id:seq:hash of the end; keep it elsewhere and pass it to a later verify.

summary()

One line for a terminal or a CI log.

CallableAuditStore

Signs and chains entries into one stream, then calls fn(record) for each.

Raises:

Type Description
ConfigError

fn is not callable, or no key or a short one.

close()

Send the seal once; a store that sent nothing sends nothing.

digest(value)

A keyed digest of value under this store's key.

write(entry)

Send one signed entry (the stream's open record first).

Raises:

Type Description
ToolUsageError

the store is closed.

IntegrationError

fn failed; the record's seq is used, so the gap shows.

FileAuditStore

Append-only, chained, signed JSONL segments in folder; one writer per folder.

Raises:

Type Description
ConfigError

no key or a short one, a bad limit, another writer, or a folder whose end does not check out (run verify).

key_id property

The public id of the signing key.

close()

Seal the active segment and release the folder; safe to call twice.

digest(value)

A keyed digest of value under this store's key.

write(entry)

Append one signed entry, rotating the segment first when due.

Raises:

Type Description
ToolUsageError

the store is closed.

IntegrationError

the store failed earlier and stopped, to keep the chain whole.

OSError

the disk write failed (rolled back).

audit(executor=None, *, folder=DEFAULT_FOLDER, key=None, store=None, max_bytes=DEFAULT_MAX_BYTES, fsync=True, fail_closed=False)

Attach a signed audit log of executor (or the default one) under folder or store.

Raises:

Type Description
ConfigError

no key or a short one, a bad limit, another writer on the folder, or the folder already audited in the other fail_closed mode.

export_to(out, path, *, since=None, until=None, format='jsonl', key=None)

Stream export's records to out after a full check; the count written.

Raises:

Type Description
ConfigError

no key, a bad format or time, or a log that is not intact (a change found while reading raises too: discard what was written).

read_entries(path, key=None)

The event records of a verified log, oldest first, one at a time.

Raises:

Type Description
ConfigError

no key, a bad folder, or a log that is not intact (checked before the first record, and again while reading).

verify_records(records, key=None)

Check shipped records in the order received; interleaved streams are checked apart.

Raises:

Type Description
ConfigError

no key, or a short one.