Skip to content

Audit Trail (audit_trail)

Tamper-evident database logging for Drupal 11.

Every entry that lands in the chain embeds an HMAC of its own payload plus the HMAC of the previous entry in the same chain. Insert, modify or delete a record after the fact and the chain breaks at every entry downstream — verification pinpoints the first broken row, and the alteration is provably detectable.

Why

Drupal's dblog module records every event you tell it to, but the rows are plain database writes. Anyone with database write access (a sysadmin, a compromised app account, an attacker who escalated through some other vulnerability) can edit a row, drop a row, or insert a fake row without a trace. For most sites that is acceptable. For audit-worthy applications — anything subject to regulated retention (notarial acts, financial transactions, medical records), or any system that needs a defensible answer to "who did what, when, with what content" — it is not.

audit_trail adds a cryptographic chain on top of selected log entries. It does not stop tampering (no logging mechanism can do that without external storage) but it makes tampering provably detectable, which is the property regulators and auditors care about.

What it does

  • Plugs into Drupal's standard logger pipeline (PSR-3 + the logger service tag), so any module that calls \Drupal::logger($channel)->info(...) can land in the chain without code changes.
  • Chains entries selectively based on either a per-call flag ('chain' => TRUE in the PSR-3 context), or mode: auto chains that capture every entry on their claimed channels automatically. mode: auto on the default chain claims only the channels it explicitly names — it does NOT wildcard every other channel, so unrelated dblog noise stays out.
  • Stores each chained entry in a dedicated audit_trail table with a publicly-verifiable SHA-256 hash chain plus an operator HMAC layer.
  • Groups entries by chain id (defaults to channel; can map multiple channels into one chain via an audit_trail_chain config entity) so verification is independent per chain.
  • Exposes a AuditTrailVerifier service to walk a chain in id order and report every contiguous broken range in a single pass.

What it does not do (yet)

  • It is tamper-evident, not tamper-proof. Anyone with the HMAC secret + database write access can forge a fresh chain from scratch — but they cannot rewrite the existing chain retroactively without breaking it. Pair with external WORM storage (S3 Object Lock, Vault transit) and a qualified RFC 3161 time-stamp on batch boundaries for legally opposable archival.
  • It does not yet ship a Drush command or admin page — see the roadmap.
  • It does not handle retention purging; deleting old rows breaks the chain. A future Drush command will export+tombstone before delete to preserve integrity.

Comparison with existing modules

Module Scope Tamper-evident?
Core dblog All log calls → DB table No
Core syslog All log calls → syslog No (file)
audit_log Entity events (Node, Taxonomy, User) → DB / pluggable No
audit_trail Selected PSR-3 calls → DB with HMAC chain Yes

The three approaches complement each other. audit_log answers "what entity changed?" with a rich entity-aware UI. audit_trail answers "did the log itself get tampered with?" with a low-level cryptographic guarantee. They can run side-by-side.

Status

Under active development. Project home is drupal.org/project/audit_trail; the canonical repository is at https://git.drupalcode.org/project/audit_trail. Published documentation: project.pages.drupalcode.org/audit_trail. Issues, merge requests and security disclosures go through the drupal.org project page.

Documentation

  • architecture.md — chain construction, cryptographic primitives, canonical form, segment lifecycle, forensic envelope.
  • configuration.md — chain / secret / settings configuration, retention policy, bucket granularity, filter plugins.
  • consumers.md — guide for code that LOGS into the chain (bridges, contributors, private routing keys).
  • verification.md — what the verifier proves and does not prove; incremental walks and signed checkpoints.
  • security.md — operator deployment guidance (secret rotation, key providers, retention policy, two-tier retention model).
  • threat-model.md — consolidated threat model for security reviewers and compliance assessors (actor matrix, defenses, non-goals, cryptographic assumptions, operator responsibilities).
  • roadmap.md — shipped scope + post-1.0 intent.