Files
safetynet/docs/audit-integrity.md

3.2 KiB

Security audit integrity

Security events and their SHA-256 chain records are committed in the same SQLite savepoint. Sigma child events are covered too. The event digest covers the exact stored event ID, timestamp, device, kind and metadata string. The chain binds its installation identity, sequence and preceding hash.

By default the chain is unsigned. It detects inconsistent changes but cannot authenticate against someone able to rewrite the database. For authenticated records, configure AUDIT_SIGNING_KEY_FILE before creating the audit chain. This is an absolute path to an external ML-DSA-87 PKCS8 PEM private key, with owner-only permissions (Windows also permits SYSTEM and Administrators). Linked paths are rejected. Private signing material is never stored in SQLite. Missing or changed signing keys fail startup; automatic key rotation is not implemented. A nonempty unsigned chain cannot be silently upgraded: plan a separately archived deployment migration.

Existing event rows at first migration become explicitly unverified legacy baselines. A signed baseline seal commits to that prefix without retroactively establishing its provenance. Existing corrupt chains fail startup rather than being reconstructed.

Analyst workflow

The central Admin console offers an explicit Verify stored audit records action. It reports internal consistency, signature authentication and independent external anchoring separately. The console performs a local check; it does not claim an independent external anchor exists.

Authenticated audit.read APIs:

  • GET /api/admin/audit/integrity: full local verification and limitations.
  • GET /api/admin/audit/entries?after=0&limit=100: reconstructable records including baseline and retention entries, public key, installation ID and current head. Sequence pagination is distinct from event-ID pagination. Maximum batch size is 1,000.

ECS exports include the event entry envelope under safetynet.audit, excluding event contents. CEF carries the entry hash and sequence; use the proof API for signatures, baseline and deletion records. An independent receiver must archive those records plus a trusted public-key pin and accepted checkpoint (sequence/hash). Neither delivery success nor a database-held cursor establishes independent cryptographic anchoring. Full database rollback or removal of a valid suffix requires comparison with such externally retained checkpoints. A compromised signing process remains outside this guarantee.

Retention and operations

Only exported, unreferenced events are eligible for existing deployment retention. Before removal, exact current event digests are checked and a chained authorization lists the specific IDs and hashes. Chain records and authorization events remain; event plaintext can be deleted without losing the verification linkage. Incident/evidence holds and replay deduplication continue to apply.

Verification scans the chain synchronously and currently loads it into memory. Very large production installations need incremental verification, bounded jobs, independently durable checkpoint delivery and archive compaction. The retained proof chain is not yet compacted and grows over time. audit.verify is an OpenTelemetry stage with timing and outcome, without event content or signing material.