Who moved fifty accounts? Only a good audit log can tell you
Someone reassigned fifty dealer accounts and now denies it. Whether your software can name which accounts and who did it depends on how the log was built.
Somebody on your sales team moved fifty dealer accounts from one representative to another. Perhaps it was a slip, perhaps it was deliberate, and now they say they did not do it. You need to know exactly which fifty accounts, and who.
In the distributor platform we built, one action can do this: reassign fifty or more accounts in a single go, with no approval step and no second pair of eyes. When that happens, the audit log is the only record. A log that says “fifty accounts reassigned” is useless, because that is the size of the event and you need its contents. Reconstructing which fifty is the entire reason the log exists.
Most audit logs are built to tick a compliance box and turn out to be inadequate on the one day they matter. The cost on that day is an argument you cannot settle, between people you both employ, with money and trust on the line.
What was actually going on
The first decision was that nobody writes audit entries by hand. A line added to each feature gets forgotten, reliably, because adding it makes no difference to whether the feature works, so it is the step dropped under time pressure and the one a reviewer does not notice missing. A log with gaps is worse than no log, because people trust it. A missing entry gets read as proof that nothing happened, when it means somebody forgot a line six months ago.
What we changed
So capture happens in one place. Every change to the system passes through a single recorder after login, which writes a row when the request finishes. New features are covered by default, and failed attempts are recorded too, which are often more interesting than successful ones. Who, what, where and the outcome are captured the same way every time, because they come from the request and not from what each developer remembered to include.
What is stored is a deliberately chosen subset of each request, not the whole thing. A log lasts a long time and many people can read it, so storing everything means storing passwords, personal details and payment information. The chosen subset is what stops your audit log becoming your worst data exposure.
Central capture does not give events meaningful names, because the recorder only sees what was requested and where. So names come from a lookup, and anything it does not recognise is saved under a label meaning “an unrecognised change”. Here is the useful part: periodically we list everything under that label, grouped by where it came from, and add names for the ones that matter. The gap list writes itself from real use, in order of how often each gap happens, which beats someone reading every possible route and naming them all.
What it did not fix
Checking the recorder against the list of everything the system can do found real gaps, and they cluster. One whole group of features, the one handling photographs and product images, had no recording at all. Centralising had moved the forgettable step, not removed it, because connecting the recorder is still done once per group of features.
Sign-in events, failed logins and refreshed sessions, were not logged, because the recorder deliberately skips the sign-in routes. That is reasonable on the face of it, but failed logins are among the most valuable events any system can record, and a skip written once at the top of a file is invisible in review. And several changes were captured but labelled only generically, so they were present in the log and not findable in it.
Keeping the log for a stated period was deliberately left to a later phase, written down as deferred instead of assumed. In a related system the design document said the log table was split by month so old months could be archived. It was not split, and nothing was archiving anything. The only reason anyone knew is that somebody checked the database, not the document.
The gaps above are what one cross-check found. This page does not claim they are all closed, or that no others remain. And a log can only answer the question it was designed for: it will say who moved the accounts, not whether they should have been allowed to.
The pattern, for anyone who relies on an audit log
Ask these of your own system, and ask your supplier to show you, not tell you.
- If someone disputes an action from last month, can you see exactly what changed, by whom, and to which specific records?
- Are failed and refused attempts recorded, or only successes?
- What is deliberately left out, and when was that list last looked at?
- How do you find out about a kind of event the log does not recognise?
- Is anything in the log that should not be, such as passwords or a full payment record?
- Does the retention the documents describe actually exist in the database?
Whatever a design document says, check the thing itself. A document states intent. Whether the intent was carried out is answered by looking.
Where this ends up
That is the shape of the audit trail behind Field: captured in one place rather than by hand, named from a lookup, and able to list the events it has not yet learned to name.