audit
azure_bootstrap.audit
¶
Audit log conventions.
Standardize the audit-line pattern so PII/secret leakage at log call sites
is handled consistently. Mask email-shaped values via the v2
:func:mask_email_address helper; non-email secrets via :func:mask_api_key;
truncate / strip control chars from text fields via :func:sanitize_for_log.
Always inserts a UTC ISO-8601 timestamp and the operation name into the extras dict so structured aggregators have a stable schema.
Hash-chained audit records (v3)¶
:class:ChainedAuditRecord is a dataclass whose record_hash field is a
SHA-256 digest of the canonical JSON representation of all other fields
(including prev_hash). :class:AuditChain sequences records so that
each record's prev_hash equals the preceding record's record_hash,
making undetected tampering computationally infeasible.
Usage::
def store(record: ChainedAuditRecord) -> None:
db.insert(record) # or blob, queue, etc.
chain = AuditChain(storage_fn=store)
r1 = chain.append_chained("LOGIN", actor="alice", resource="/portal")
r2 = chain.append_chained("EXPORT", actor="alice", resource="/report/42")
ok = verify_chain([r1, r2]) # True if untampered
Classes:
| Name | Description |
|---|---|
ChainedAuditRecord |
An immutable audit event linked to its predecessor via |
AuditChain |
Thread-safe, append-only sequence of :class: |
Functions:
| Name | Description |
|---|---|
mask_email_field |
Ergonomic alias of :func: |
truncate_field |
Apply |
build_audit_extra |
Construct the |
verify_chain |
Verify the integrity of an ordered list of :class: |
ChainedAuditRecord
dataclass
¶
ChainedAuditRecord(id: str, ts: str, event_type: str, actor: str, resource: str, detail: dict[str, Any], prev_hash: str | None, record_hash: str = '')
An immutable audit event linked to its predecessor via prev_hash.
Fields¶
id
UUID4 string uniquely identifying this record.
ts
UTC ISO-8601 timestamp (Z suffix) at creation time.
event_type
Caller-supplied label such as "LOGIN", "EXPORT", "DELETE".
actor
Identity performing the action (user, service principal, system).
resource
The object or endpoint being acted upon.
detail
Arbitrary key-value metadata; must be JSON-serialisable.
prev_hash
record_hash of the preceding record, or None for the chain head.
record_hash
SHA-256 hex digest of the canonical JSON of all other fields.
Computed automatically by :meth:__post_init__ when left as the
empty-string sentinel "".
AuditChain
¶
AuditChain(storage_fn: Callable[[ChainedAuditRecord], None])
Thread-safe, append-only sequence of :class:ChainedAuditRecord objects.
Each new record's prev_hash is set to the record_hash of the most
recently appended record (or None for the very first record), forming a
cryptographic chain of custody.
Parameters¶
storage_fn:
Callable invoked with each new :class:ChainedAuditRecord immediately
after it is appended. Suitable for writing to a database, blob store,
audit queue, or any other durable sink. The callable is invoked while
the internal lock is not held, so it may perform I/O without blocking
concurrent appends.
Methods:
| Name | Description |
|---|---|
append_chained |
Create and store a new :class: |
verify_chain |
Verify a sequence of :class: |
Source code in azure_bootstrap/audit/__init__.py
append_chained
¶
append_chained(event_type: str, actor: str, resource: str, detail: dict[str, Any] | None = None) -> ChainedAuditRecord
Create and store a new :class:ChainedAuditRecord.
Parameters¶
event_type:
Short label identifying the kind of action (e.g. "LOGIN").
actor:
Identity performing the action.
resource:
The object or endpoint being acted upon.
detail:
Optional mapping of additional metadata. Defaults to {}.
Returns¶
ChainedAuditRecord
The newly created record, already passed to storage_fn.
Source code in azure_bootstrap/audit/__init__.py
verify_chain
¶
verify_chain(records: list[ChainedAuditRecord]) -> bool
Verify a sequence of :class:ChainedAuditRecord objects is untampered.
Delegates to the module-level :func:verify_chain function.
Source code in azure_bootstrap/audit/__init__.py
mask_email_field
¶
truncate_field
¶
Apply AUDIT_TRUNCATED_FIELDS truncation when applicable.
Source code in azure_bootstrap/audit/__init__.py
build_audit_extra
¶
Construct the extra={} dict for an audit log call.
Email-shaped values for masked fields go through :func:mask_email_address;
other masked values through :func:mask_api_key. Truncated fields get
:func:sanitize_for_log applied with the configured cap.
Always adds operation and a UTC ISO-8601 timestamp.
Source code in azure_bootstrap/audit/__init__.py
verify_chain
¶
verify_chain(records: list[ChainedAuditRecord]) -> bool
Verify the integrity of an ordered list of :class:ChainedAuditRecord objects.
For each record the function recomputes the expected record_hash from
the record's fields and confirms it matches the stored record_hash. It
also verifies that each record's prev_hash equals the preceding record's
record_hash (or None for the first record).
Returns True if the chain is intact, False on the first detected
anomaly (and logs a warning with tamper-evidence details).
Parameters¶
records:
Ordered list of records as originally produced by
:meth:AuditChain.append_chained.