An auditor asks who changed a customer's credit limit last March, and why. If the answer lives in an email thread and a spreadsheet with three versions, someone loses two days rebuilding it. If it lives in the system that made the change, it takes a minute.
That gap is what most "risk and audit management" projects are really about. Not dashboards, not scoring models: a clear record of who did what, when, and on whose approval, kept by the software itself.
This post covers what an audit-ready system has to record, when an off-the-shelf GRC tool (governance, risk and compliance software) is enough, and when it pays to build the tracking into your own platform.
What auditors actually ask for
Whatever the framework (SOC 2, ISO 27001, a financial audit or a client's security questionnaire), the questions come back to a short list:
Who did it. A named user, not a shared account.
What changed. The value before and after, not just "record updated".
When. A timestamp the user cannot edit.
On whose approval. For sensitive actions, the second person who signed off.
What was done about findings. An owner, a due date and a closed status for each corrective action.
Proof it still holds. Evidence that access rights and controls are reviewed, not set once and forgotten.
If your systems can answer those six from their own data, audits get short. If people have to reconstruct them from memory and inboxes, audits get long and findings pile up.
Three ways to get there
There is no single right answer. It depends on where the risky actions happen.
| Option | Fits when | Watch out for |
|---|---|---|
| Off-the-shelf GRC software | You need policies, risk registers, control testing and evidence collection across many tools | It records that a control exists, not what happened inside your own app |
| Audit features inside your platform | The risky actions (prices, payments, permissions, approvals) happen in software you own | Needs to be designed in, with tests, or it drifts |
| Both | You report to a framework and also run a custom platform | Two systems to keep in sync; agree which one is the source of truth |
For many companies we talk to, the answer is the third row. The GRC tool holds the policies and the evidence folder. The platform where the money and the data move keeps its own trail, and exports what the GRC tool needs.
What "built in" means in practice
Adding an audit trail to an existing app is mostly plumbing, but the details decide whether an auditor trusts it.
An append-only activity log. Every create, update and delete on sensitive records writes an entry with the user, the old and new values and the time. Nobody, including admins, can edit those entries from the app.
Approvals as data. A discount above a threshold or a refund goes into a pending state and records who approved it. The approval is a row in the database, not a Slack message.
Roles that match real jobs. The accountant can export invoices but not change prices. Permission changes are logged like any other change.
Findings with owners. Each issue gets an assignee, a due date and a status, with reminders, so nothing sits open for a quarter.
Exports the auditor can read. A filtered CSV or PDF of the log for a period, instead of database access.
Tests that prove it. Automated tests that fail if a sensitive action stops writing its log entry. Without them, the trail quietly breaks during the next feature.
An example: certificates anyone can verify
Marafiq runs exam-prep courses for facilities-management professionals. When a learner passes, the platform issues a PDF certificate with a serial number and a QR code. Anyone (an employer, an accrediting body) can scan the code and check the certificate against the platform's public verification page.
That is an audit question solved by design: "is this certificate real, and who earned it?" is answered by the system, not by an email to the training provider. The same platform runs about 940 automated tests on every change, so features like this keep working as the product grows. The build is described in the Marafiq case study.
The pattern carries to other domains. A purchase approval, a price change or a permission grant can carry the same kind of proof: a record the system writes, that people can check and nobody can quietly edit.
What moves the cost
Audit features are rarely expensive on their own. The cost comes from the state of the app they go into.
| Factor | Smaller job | Bigger job |
|---|---|---|
| Where changes happen | One app, through its own screens | Several apps, scripts and direct database edits |
| Approval rules | One threshold, one approver | Chains that differ by amount, region or department |
| Existing tests | Feature tests on the sensitive flows | None, so they are written first |
| History needed | From go-live onward | Past changes reconstructed from old data |
| Reporting | A filtered export | Framework-specific reports and integrations with a GRC tool |
The line that surprises people is the first one. If staff fix data directly in the database or through one-off scripts, no log in the app will catch it. Closing those side doors is part of the job, and sometimes the biggest part. The same reasoning applies to older apps in general, as we describe in modernizing a legacy Laravel app without a rewrite.
When not to build
If your risky actions happen in tools you do not own (your accounting system, your CRM, your cloud provider), building a custom audit system on top of them rarely pays. Use their own logs and a GRC tool to collect the evidence. The same goes for policy management and staff training records: buy that.
Building makes sense when the money, the prices or the permissions move inside a platform you already run, and the off-the-shelf tool can only see the outside of it. Our post on build vs. buy walks through the general version of this decision.
Next step
Bring the last audit finding or security questionnaire that took too long to answer. On an intro call we will tell you whether your platform can answer it from its own data, what it would take if not, and whether a tool you can buy does the job better. Book an intro call.

