Audit (lexigram-audit)
Unified audit trail for the Lexigram Framework — append-only, HMAC-verified, retention-managed.
Overview
Section titled “Overview”lexigram-audit provides a unified, append-only audit trail with HMAC-SHA256 tamper detection, configurable per-severity retention policies, and scheduled integrity verification batches. The AuditLogger is fire-tolerant — audit failures never interrupt business logic.
Full documentation: docs.lexigram.dev
Install
Section titled “Install”uv add lexigram lexigram-audit
# For the SQL backend (recommended for production)uv add lexigram-sqlQuick Start
Section titled “Quick Start”from lexigram import Applicationfrom lexigram.di.module import Module, modulefrom lexigram.audit import AuditModulefrom lexigram.audit.protocols import AuditLoggerProtocolfrom lexigram.contracts.audit import AuditEntry, AuditEventSeverity
@module( imports=[ AuditModule.configure( store_backend="memory", hmac_key=b"your-hmac-secret", ) ])class AppModule(Module): pass
async def main() -> None: async with Application.boot(modules=[AppModule]) as app: audit = await app.container.resolve(AuditLoggerProtocol)
await audit.log( AuditEntry( action="user.deleted", actor_id="user-123", resource_type="user", resource_id="user-42", severity=AuditEventSeverity.HIGH, ) )
if __name__ == "__main__": import asyncio asyncio.run(main())The
"sql"backend (default) requireslexigram-sqlwith aDatabaseModuleregistered;"memory"is an in-process store for development and tests.
Configuration
Section titled “Configuration”Zero-config usage: Call
AuditModule.configure()with no arguments to use all defaults.
Option 1 — YAML file
Section titled “Option 1 — YAML file”audit: store_backend: "sql" hmac_key: null retention_policy: default_retention_days: 365 enable_admin: trueOption 2 — Profiles + Environment Variables (recommended)
Section titled “Option 2 — Profiles + Environment Variables (recommended)”export LEX_AUDIT__STORE_BACKEND=sqlexport LEX_AUDIT__HMAC_KEY=your-hex-encoded-keyexport LEX_AUDIT__RETENTION_POLICY__DEFAULT_RETENTION_DAYS=365Option 3 — Python
Section titled “Option 3 — Python”from lexigram.audit import AuditModule
AuditModule.configure( store_backend="sql", hmac_key=b"your-hmac-secret", table_name="audit_log", retention_days=365, enable_admin=True,)For full control (e.g. per-severity retention overrides), build an AuditConfig directly and configure retention_policy with a RetentionPolicy from lexigram.contracts.audit:
from lexigram.audit.config import AuditConfigfrom lexigram.contracts.audit import RetentionPolicy
AuditConfig( store_backend="sql", hmac_key=b"your-hmac-secret", retention_policy=RetentionPolicy( default_retention_days=365, severity_overrides={"critical": 2555, "high": 1095}, ), enable_admin=True,)Config reference
Section titled “Config reference”| Field | Default | Env var | Description |
|---|---|---|---|
store_backend | "sql" | LEX_AUDIT__STORE_BACKEND | Storage backend: "sql" or "memory" |
table_name | "audit_log" | LEX_AUDIT__TABLE_NAME | SQL table name (SQL backend only) |
hmac_key | null | LEX_AUDIT__HMAC_KEY | HMAC-SHA256 secret key (bytes; strings are used as UTF-8 bytes, not hex-decoded); null disables tamper detection |
retention_policy.default_retention_days | 365 | LEX_AUDIT__RETENTION_POLICY__DEFAULT_RETENTION_DAYS | Default retention in days (0 = indefinite) |
retention_policy.severity_overrides | {"critical": 2555, "high": 1095} | — | Per-severity retention overrides (days) |
verification_schedule | "0 * * * *" | LEX_AUDIT__VERIFICATION_SCHEDULE | Cron expression for HMAC verification runs |
verification_batch_size | 100 | LEX_AUDIT__VERIFICATION_BATCH_SIZE | Entries verified per scheduled run |
enable_admin | true | LEX_AUDIT__ENABLE_ADMIN | Enable admin dashboard integration |
Module Factory Methods
Section titled “Module Factory Methods”| Method | Description |
|---|---|
AuditModule.configure(*, hmac_key=None, store_backend="sql", table_name="audit_log", retention_days=365, enable_admin=True) | Configure the audit module (keyword arguments only) |
Key Features
Section titled “Key Features”- Fire-tolerant logging —
AuditLogger.log()never blocks calling code; errors are logged at WARNING and swallowed - HMAC-SHA256 checksums — per-entry tamper detection verified on schedule or on-demand
- Per-severity retention —
PolicyBasedRetentionapplies different retention periods per severity level - SQL backend — append-only
SqlAuditStorebacked bylexigram-sql - Memory backend — bounded in-process store for development and testing
- Admin dashboard —
AuditAdminContributoradds an Audit Log panel - Scheduled verification — hourly HMAC batch verification when a task scheduler is present
Testing
Section titled “Testing”import pytestfrom lexigram import Applicationfrom lexigram.audit import AuditModulefrom lexigram.audit.protocols import AuditLoggerProtocol, AuditStoreProtocolfrom lexigram.contracts.audit import AuditEntry, AuditQuery
@pytest.mark.asyncioasync def test_audit_log_records_entry() -> None: async with Application.boot( modules=[AuditModule.configure(store_backend="memory")] ) as app: audit = await app.container.resolve(AuditLoggerProtocol) store = await app.container.resolve(AuditStoreProtocol)
await audit.log( AuditEntry( action="user.created", actor_id="actor-1", resource_type="user", resource_id="user-42", ) )
entries = await store.query(AuditQuery(action="user.created")) assert len(entries) == 1 assert entries[0].actor_id == "actor-1"Key Source Files
Section titled “Key Source Files”| File | What it contains |
|---|---|
src/lexigram/audit/module.py | AuditModule.configure(), .stub() |
src/lexigram/audit/config.py | AuditConfig, RetentionPolicyConfig |
src/lexigram/audit/di/bundle_provider.py | AuditBundleProvider boot and registration |
src/lexigram/audit/logging/logger.py | AuditLogger (fire-tolerant entry point) |
src/lexigram/audit/store/memory.py | InMemoryAuditStore |
src/lexigram/audit/store/sql.py | SqlAuditStore |
src/lexigram/audit/verification/checksum.py | HMAC-SHA256 checksum logic |
src/lexigram/audit/retention/policy.py | PolicyBasedRetention |
src/lexigram/audit/admin/contributor.py | AuditAdminContributor |