All guides

Security

Who changed what: an activity log for WordPress that stands up as evidence

Why every multi-user WordPress site needs an audit trail, what a good one records, how a hash-chained log proves it has not been edited, and how to use it in an incident.

4 min readUpdated

The question you cannot answer without one

A page's price changed. A plugin appeared that nobody installed. A user account has a new email address. On a site with more than one person in wp-admin, "who did this and when" is unanswerable from WordPress itself: revisions cover post content and nothing else, and there is no record of logins, settings changes, plugin activations or user edits at all.

An activity log answers it. It is the first thing you open in an incident, the thing a client asks for when their site changed and they did not do it, and the thing auditors mean when they say "access logs".

What a useful log records

Install Dragon Activity Log and it starts recording immediately under Tools, then Activity Log:

  • Content changes with field-level detail. Not "post updated" but which fields changed, with the before and after values.
  • Logins, logouts, failed logins and profile changes, attributed to the user signing in, with the address if you enable IP capture.
  • Plugin, theme and core updates, activations and deactivations.
  • Settings changes, including the log's own settings.
  • Media, taxonomy terms and comments.
  • Events from other Dragon plugins, such as Redirect Manager rule changes, when they are active.

Field-level detail: who changed what, the exact before and after values, with secrets redacted.
Field-level detail: who changed what, the exact before and after values, with secrets redacted.

Anything that looks like a secret (passwords, tokens, API keys, salts) is stored as redacted, so the log never becomes the thing that leaks.

Reading it under pressure

Filter by object type, event, severity and date, or search. Severity pills (info, notice, warning, critical) put the rows that matter at the top of your eye. The live updates toggle streams new events onto the first page, which is what you want open on a second screen during a deploy or a suspected intrusion.

In an incident the sequence is: find the first suspicious event, filter by that user, walk forward. A compromised account's trail usually reads: login from a new address, a plugin installed or a user created, then settings changed. Each row tells you what to undo.

Why "tamper-evident" is the part that matters

A log that sits in the same database as everything else can be edited by anyone who can edit the database, including the intruder. Dragon Activity Log seals every event into a hash chain: each entry carries a SHA-256 hash of the one before it. The Integrity tab verifies the whole chain and names the first entry that no longer matches if anything was altered or deleted directly in the database.

Two honest limits: a row deleted before it is sealed (sealing runs hourly, plus an occasional end-of-request pass) leaves no trace, and someone with database write access who recomputes every later hash can hide an edit. That second gap is closed by the off-site anchor: on a schedule, the chain head (an event number and hash, never event data) is emailed to an address outside the site, or POSTed to a webhook you control, signed. Compare with an anchor later proves the chain up to that point is unchanged. Set the anchor email up now, to an address that is not on the site's own domain; it is one field.

Site Health shows an "Activity log integrity" test that goes red naming the first broken event, so you do not have to remember to check.

Undo, alerts and export

Since version 1.1.0 the log also helps you act on what it shows, free:

  • Roll back a change. Open Full details on a setting change or a role change and put it back with one click. It only runs while the setting or the user's roles still hold exactly what the event left behind, and the rollback is itself logged. Post edits stay with WordPress's own revisions and Trash.
  • Full before and after. Post and setting events keep a copy of the state on both sides of the change, so you see the whole value side by side, with anything that looks like a secret left out.
  • Security alerts by email when someone logs in from an address they have not used before, when one address racks up a burst of failed logins, or when a user is made administrator. Off until you switch them on under Settings.
  • CSV and JSON export of the events matching your current filters, for an incident report or a client.
  • WooCommerce events: new orders, status changes, stock changes and new coupons.

Retention and privacy

Set retention in days under Settings (0 keeps everything). Logged events can contain personal data, so decide deliberately: 90 days is common, a year for regulated sites. IP capture is optional and can be anonymised; if you trust proxy headers, list your proxies. The plugin integrates WordPress's privacy tools, so a user's export and erasure requests cover their events. Uninstalling keeps the log by default, because an audit trail you can lose by clicking uninstall is not much of an audit trail.

Pairs with

The CRA checklist is where an audit trail becomes a requirement rather than a nice-to-have.