Building compliant software in financial services / The rules that apply to your code
SEC recordkeeping requirements in your application
The SEC's 2022 amendments gave electronic recordkeeping systems an alternative to write-once storage: a complete time-stamped audit trail that permits re-creation of the original record. It is a far better fit for modern applications, and it is a stricter engineering requirement than most teams realise.
Published August 22, 2026. Editorial.
Key takeaways
- The audit-trail alternative requires recording modifications, deletions, timestamps, and the identity of the individual acting, in a way that permits re-creation of the original record.
- Re-creation is the requirement most systems fail, and it cannot be verified by reading code. You have to modify a record and reconstruct the prior state from the trail alone.
- The system must be able to download a record and its audit trail in both human-readable and reasonably usable electronic formats.
- Soft deletes are not automatically compliant. A soft delete that overwrites prior field values fails re-creation just as a hard delete does.
For years, the practical reading of SEC Rule 17a-4 was that electronic records had to sit in write-once, read-many storage. That constraint shaped financial software for many years, usually by pushing records into a separate archival system that the application wrote to and nobody else touched.
The 2022 amendments changed the options. The rule now permits an audit-trail alternative alongside the WORM approach, and for most modern applications the audit-trail route is both a better architectural fit and, read carefully, a more demanding engineering requirement.
What the rule actually says
The operative language is worth reading rather than paraphrasing. An electronic recordkeeping system must preserve a record for the duration of its retention period in a manner that maintains a complete time-stamped audit trail that includes all modifications to and deletions of the record or any part thereof, the date and time of actions that create, modify, or delete the record, if applicable the identity of the individual creating, modifying, or deleting the record, and any other information needed to maintain an audit trail in a way that maintains security, signatures, and data to ensure the authenticity and reliability of the record and will permit re-creation of the original record if it is modified or deleted [1].
The alternative is to preserve records exclusively in a non-rewriteable, non-erasable format [1], which is the older WORM option and remains available.
Two further requirements come with it and are often missed. The system must verify automatically the completeness and accuracy of the processes for storing and retaining records electronically. And it must have the capacity to readily download and transfer copies of a record and its audit trail in both a human readable format and in a reasonably usable electronic format [1].
The four assertions in one sentence
Converted into engineering requirements, that paragraph produces a short list, and the difficulty is unevenly distributed across it.
Every create, modify, and delete produces an entry. Straightforward. Most teams have this, usually through database triggers or an application-level audit table.
Every entry carries a timestamp. Also straightforward, with one risk: the timestamp needs to be unambiguous. A local-time timestamp with no zone, or one that shifts under daylight saving, is a real problem in a reconstruction three years later.
Every entry names the individual. This is where the first genuine failures appear, and there are three common ones. Background jobs write as a service account, which is correct but only if the entry also records what triggered the job and on whose behalf. Bulk operations record one actor for a thousand rows, which is usually fine, but only if the trail links them. And administrative impersonation, where a support user acts as a customer, often records the customer as the actor. That last one is not a small defect. It means the trail asserts that a customer did something a member of staff did, which is worse than no entry at all, because it is confidently wrong.
The original is recoverable. This is the hard one, and it is the requirement that separates systems that pass from systems that look like they pass.
Why re-creation is the requirement that fails
Most audit implementations record that a change happened. Far fewer record enough to reconstruct what the record was before it.
The typical pattern is an audit table with an action, a timestamp, an actor, and a record identifier. That satisfies three of the four assertions and fails the fourth completely, because knowing that customer record 4471 was modified at a given time by a given user does not let you reconstruct its prior state. To do that you need either the prior values, the changed values plus enough history to replay, or an append-only design where nothing is ever overwritten in the first place.
Soft deletes deserve specific attention here, because teams treat them as the compliant option and they are not automatically compliant. A soft delete that sets a deleted flag and leaves the row otherwise intact preserves re-creation. A soft delete that sets the flag and also blanks or anonymises the fields, which many do for privacy reasons, destroys it. The two look nearly identical in the code and behave completely differently under the rule.
There is a genuine tension here worth naming, because pretending it does not exist helps nobody. Recordkeeping obligations push towards preserving everything, and privacy obligations push towards deleting on request. They are resolved by retention periods and by scoping which records are covered, not by picking one and ignoring the other, and that resolution is a legal question rather than an engineering one. What engineering must contribute to the discussion is an accurate account of what the system currently does, which is frequently different from what the team believes.
How to check it, properly
The re-creation requirement cannot be verified by inspection. Reading the schema tells you what could be reconstructed in principle. It does not tell you what actually can be, because the answer depends on application behaviour that the schema does not capture.
The check that works is a full cycle test, run as an automated test:
Create a covered record with known values. Modify several fields, including at least one that the application treats specially, such as an encrypted field or one that triggers a downstream sync. Delete it, by whatever mechanism the application actually offers users. Then, using only the audit trail, reconstruct the record as it stood before each change, and assert that the reconstruction matches what you created.
Run that for every covered record type rather than one representative example. The failures are almost never uniform. A system will handle its core entity correctly and fail on the three peripheral ones that were added later by a different team under time pressure, and those peripheral ones are exactly the ones nobody thinks to test manually.
Then add the export requirement to the same suite: assert that the record and its trail can be produced in a human-readable form and in a reasonably usable electronic form [1]. Teams often satisfy this with an ad hoc database query run by an engineer, which works right up until the examination arrives and the engineer who knew the query has left.
The retention side
Preserving the trail for the duration of the applicable retention period is part of the same requirement, and retention is its own source of unnoticed failures.
The common pattern is that retention is enforced somewhere other than where data actually leaves. A policy says records are kept for the required period and then disposed of, and the implementation is a scheduled job over the primary table. Meanwhile the analytics replica, the backup snapshots, the log aggregator, and the export bucket each have their own lifecycle, usually set by whoever configured them, usually not aligned with the policy. Records that should have been disposed of survive in three places, and records that should have been preserved get deleted from a backup tier on a ninety-day default.
Both directions are failures. Checking them means enumerating every place a covered record can be stored, which is a discovery exercise before it is an engineering one, and which is covered on how to audit an existing financial application.
Rules change and this page is a starting point for engineering work, not legal advice about which records are covered in your business. Get that scoping from counsel, then bring it here and turn it into checks. If you want help doing that, get in touch.
Best for
- Systems where records are updated in place and an append-only redesign is impractical
- Teams that want records to live in the application database rather than a separate archival product
Avoid if
- Your retention scope has not been decided yet, since the audit trail requirement applies to covered records and you need to know which those are
Check before you decide
- Run the full cycle test: create, modify, delete, then reconstruct from the trail alone and compare
- Check whether administrative impersonation records the staff member or the impersonated customer
- Check whether your soft delete preserves prior field values or blanks them
- Enumerate every place a covered record is stored, then compare each one's lifecycle against the retention policy
Common questions
What is the audit-trail alternative under SEC Rule 17a-4?
It is the option, added by the 2022 amendments, to preserve electronic records with a complete time-stamped audit trail instead of exclusively in non-rewriteable, non-erasable storage. The trail must cover modifications and deletions, record the date and time and the identity of the individual acting, and permit re-creation of the original record if it is modified or deleted.
Does a soft delete satisfy the re-creation requirement?
Only if it preserves the prior field values. A soft delete that sets a deleted flag and leaves the row intact preserves re-creation, while one that also blanks or anonymises the fields destroys it, and the two are nearly identical in the code.
Why can't I verify re-creation by reading the schema?
Because the schema tells you what could be reconstructed in principle, not what actually can be, and the difference is application behaviour the schema does not capture. The only reliable check is a full cycle test: create a record, modify it, delete it, then reconstruct the prior states from the trail alone and compare.
What does administrative impersonation do to an audit trail?
It often records the impersonated customer as the actor rather than the staff member, which is worse than recording nothing. The trail then asserts that a customer took an action a member of staff took, which is confidently wrong in a record a regulator may rely on.
How do recordkeeping and deletion-on-request obligations fit together?
They are resolved by retention periods and by scoping which records are covered, not by choosing one obligation over the other. That resolution is a legal question, and what engineering must contribute to the discussion is an accurate account of what the system currently does, which is frequently different from what the team believes.
Is the audit-trail alternative always a better choice than WORM storage?
Not automatically. WORM storage remains available under the rule and can be a simpler fit for a system built around a separate archival store that nothing else touches. The audit-trail alternative tends to suit applications where records are updated in place, but it carries the stricter re-creation requirement, which many teams underestimate.
How do you test whether an application actually satisfies the re-creation requirement?
Run it as a full cycle test rather than inspecting the schema. Create a covered record, modify several fields including at least one handled specially such as an encrypted field, delete it through the path a real user would use, then reconstruct the prior states from the audit trail alone and compare them to what was created.
What is the risk of getting SEC recordkeeping requirements wrong?
An application can look compliant, pass a penetration test, and still fail to reconstruct a deleted or modified record when an examiner asks for it, which is the specific failure Rule 17a-4(f) exists to prevent. The rule generally treats the audit trail's re-creation capability as core to the recordkeeping obligation, not an optional extra.
Related reading
What a good technical spec looks like when a model writes the code
The old advice was to keep specs short and stop where writing the code is faster. That advice assumed a person was reading it. When a model writes the code, the cost of an unanswered question changes, and so does the right length of a spec.
Adding eval tests was the best decision we made
We generate every line of code we release. The single change that made that safe was writing the check before the code, and it turned out to change how we review, how we spec, and how fast we can work.
More in The rules that apply to your code
The FTC Safeguards Rule for product teams
Most engineers meet the Safeguards Rule as a security questionnaire. Read the rule itself and it is more specific than that, and it applies to your development process directly: secure development practices, change management procedures, and logging of authorized user activity are named requirements, not recommendations.
Audit trails that satisfy an examiner
Almost every financial application has an audit log. Far fewer have a trail that answers the questions an examiner actually asks, which are about a specific record on a specific day and the person who accessed it. This page covers the difference, and the six failures that turn a log into an unusable one.