Audit Trail Design
Produce a complete audit logging specification for a regulated business process, covering event catalog, data schema, immutability mechanisms, retention schedule, access controls, and examination query patterns.
Step 1: Event Catalog
Enumerate every action that must be logged. For each workflow, identify:
Standard event categories:
- Create — Record, account, policy, loan, or document created
- Read (sensitive only) — PII accessed, credit report pulled, account viewed by non-owner
- Update — Field value changed (capture before/after)
- Delete (or archive) — Record removed or soft-deleted
- Status change — Workflow state transition (e.g., submitted → approved → issued)
- Authorization — Access granted, permission changed, role assigned
- Export/Download — Data exported to file, report generated, document downloaded
- Communication — Email sent, disclosure delivered, adverse action notice issued
- Integration — Data sent to or received from external system (AMS, LOS, AUS, carrier portal)
- System — Login, logout, session timeout, failed authentication, configuration change
For each event, assign:
- Event code (e.g.,
POL.BIND.001) — namespace by domain and action
- Description — Plain English description of what occurred
- Trigger — What user action or system event causes this log entry
- Frequency — Expected volume (per day / per transaction)
- Regulatory driver — Which regulation requires this event to be logged (or "business requirement" if not regulatory)
Step 2: Required Fields per Event
Every audit log record must capture these fields as a minimum:
| Field |
Type |
Description |
Regulatory Basis |
event_id |
UUID |
Unique identifier for this log entry |
Tamper-evidence |
event_code |
string |
Structured event code from catalog |
Searchability |
event_timestamp |
ISO 8601 UTC |
When the event occurred (server time, not client) |
All regs |
actor_id |
string |
Authenticated user ID who caused the event |
FINRA 4511, SOX 404 |
actor_role |
string |
Role/permission level of the actor at time of event |
Segregation of duties |
actor_ip |
string |
Client IP address |
Security |
session_id |
UUID |
Session identifier linking related events |
Forensics |
correlation_id |
UUID |
Business transaction ID spanning multiple events |
Traceability |
object_type |
string |
Entity type affected (Policy, Loan, Client, User) |
Context |
object_id |
string |
ID of the affected record |
Searchability |
before_value |
JSON |
Field values before the change (for Update events) |
SOX, FINRA |
after_value |
JSON |
Field values after the change (for Update events) |
SOX, FINRA |
result |
enum |
success | failure | partial |
Completeness |
failure_reason |
string |
If result = failure, why it failed |
Debugging |
source_system |
string |
Which system generated the event |
Multi-system audit |
data_classification |
enum |
public | internal | confidential | restricted |
Privacy |
For events involving PII or PHI, also capture:
data_subject_id — ID of the individual whose data was accessed
access_purpose — Business purpose for accessing the data (required for GLBA/CCPA)
Step 3: Immutability Mechanisms
The audit log must be tamper-evident and append-only. Choose one or more mechanisms based on client infrastructure:
Database-level:
- Append-only table with no UPDATE or DELETE permissions for any application role
- Database trigger that blocks UPDATE/DELETE and alerts on attempt
- Row-level hash:
SHA-256(event_id + event_timestamp + actor_id + object_id + content_hash_of_all_fields) stored in each row
- Periodic Merkle root calculation (batch of N records → root hash stored separately)
Storage-level:
- Write-Once Read-Many (WORM) storage for log exports (AWS S3 Object Lock, Azure Blob immutability policy)
- Automated daily export to immutable cold storage with hash verification
Cryptographic chaining:
- Each record contains
previous_record_hash — SHA-256 of the previous record's full content
- Chain integrity verification: daily automated job validates the hash chain; alerts on break
Third-party:
- Immutable audit log service (e.g., AWS CloudTrail, Azure Monitor, Splunk SIEM) as secondary sink
- Records written to primary DB and secondary immutable service simultaneously
Step 4: Retention Schedule
| Event Category |
Minimum Retention |
Maximum Retention |
Regulatory Citation |
| Insurance policy transactions |
5 years post-policy expiration |
7 years |
State DOI (varies; use most restrictive) |
| Insurance claims records |
5 years post-close |
10 years |
State DOI claims regulations |
| Mortgage origination records |
3 years |
5 years |
RESPA § 1024.9 |
| HMDA LAR data |
3 years |
Permanent |
Reg C § 1003.5 |
| BSA/AML suspicious activity |
5 years |
Permanent |
31 CFR 1020.320 |
| FINRA communications |
3 years (first 2 easily accessible) |
6 years |
FINRA Rule 4511 |
| SOX financial controls |
7 years |
Permanent |
SOX § 802 |
| Login/authentication logs |
1 year |
3 years |
SOC 2 / general security |
| Failed authentication |
90 days |
1 year |
Security best practice |
| System configuration changes |
3 years |
7 years |
SOX ITGC |
Legal hold: Any record subject to litigation hold must be retained until hold is released, regardless of standard retention period. Implement a legal hold flag that overrides automated deletion.
Step 5: Access Controls
| Role |
Permissions |
| Application services |
INSERT only — no SELECT, UPDATE, DELETE |
| Compliance officer |
SELECT with full field access, CSV export |
| Internal audit |
SELECT with full field access, read-only |
| IT operations |
SELECT on non-PII fields only; PII masked |
| Legal |
SELECT with full access during litigation hold |
| Regulators (examination) |
Read-only export of scoped date range |
| No role |
DELETE or UPDATE (blocked at DB and application layer) |
All access to the audit log itself must be logged in a separate meta-audit log (log of logs).
Step 6: Examination Query Patterns
Design indexed queries for the most common regulatory examination scenarios:
-- All actions by a specific user in a date range
SELECT * FROM audit_log
WHERE actor_id = :user_id
AND event_timestamp BETWEEN :start_date AND :end_date
ORDER BY event_timestamp;
-- All changes to a specific record
SELECT * FROM audit_log
WHERE object_type = :entity_type AND object_id = :record_id
ORDER BY event_timestamp;
-- All failed authentication attempts
SELECT * FROM audit_log
WHERE event_code = 'AUTH.LOGIN.FAIL'
AND event_timestamp >= :start_date
ORDER BY event_timestamp;
-- All disclosures delivered (for TRID/ECOA examination)
SELECT * FROM audit_log
WHERE event_code IN ('DISC.LE.DELIVER', 'DISC.CD.DELIVER', 'DISC.ADVERSE.DELIVER')
AND event_timestamp BETWEEN :start_date AND :end_date;
-- Chain integrity verification
SELECT event_id, event_timestamp,
SHA256(CONCAT(event_id, event_timestamp, actor_id, object_id, content)) AS computed_hash,
stored_hash,
(computed_hash = stored_hash) AS hash_valid
FROM audit_log
ORDER BY event_timestamp;
Output Format
Deliver four artifacts:
- Event Catalog Table — All events with code, description, trigger, frequency, regulatory driver
- Data Schema — Full field definition table with types, constraints, and regulatory basis
- Retention Matrix — Retention schedule table with regulatory citations
- Access Control Specification — Role permission matrix and meta-audit requirements
1---2name: audit-trail3description: Design audit log specifications for regulated business processes. Use when a workflow requires a defensible audit trail for FINRA examinations, state insurance audits, SOX controls testing, or internal compliance reviews.4---56# Audit Trail Design78Produce a complete audit logging specification for a regulated business process, covering event catalog, data schema, immutability mechanisms, retention schedule, access controls, and examination query patterns.910## Step 1: Event Catalog1112Enumerate every action that must be logged. For each workflow, identify:1314**Standard event categories:**15- **Create** — Record, account, policy, loan, or document created16- **Read** (sensitive only) — PII accessed, credit report pulled, account viewed by non-owner17- **Update** — Field value changed (capture before/after)18- **Delete** (or archive) — Record removed or soft-deleted19- **Status change** — Workflow state transition (e.g., submitted → approved → issued)20- **Authorization** — Access granted, permission changed, role assigned21- **Export/Download** — Data exported to file, report generated, document downloaded22- **Communication** — Email sent, disclosure delivered, adverse action notice issued23- **Integration** — Data sent to or received from external system (AMS, LOS, AUS, carrier portal)24- **System** — Login, logout, session timeout, failed authentication, configuration change2526For each event, assign:27- **Event code** (e.g., `POL.BIND.001`) — namespace by domain and action28- **Description** — Plain English description of what occurred29- **Trigger** — What user action or system event causes this log entry30- **Frequency** — Expected volume (per day / per transaction)31- **Regulatory driver** — Which regulation requires this event to be logged (or "business requirement" if not regulatory)3233## Step 2: Required Fields per Event3435Every audit log record must capture these fields as a minimum:3637| Field | Type | Description | Regulatory Basis |38|-------|------|-------------|-----------------|39| `event_id` | UUID | Unique identifier for this log entry | Tamper-evidence |40| `event_code` | string | Structured event code from catalog | Searchability |41| `event_timestamp` | ISO 8601 UTC | When the event occurred (server time, not client) | All regs |42| `actor_id` | string | Authenticated user ID who caused the event | FINRA 4511, SOX 404 |43| `actor_role` | string | Role/permission level of the actor at time of event | Segregation of duties |44| `actor_ip` | string | Client IP address | Security |45| `session_id` | UUID | Session identifier linking related events | Forensics |46| `correlation_id` | UUID | Business transaction ID spanning multiple events | Traceability |47| `object_type` | string | Entity type affected (Policy, Loan, Client, User) | Context |48| `object_id` | string | ID of the affected record | Searchability |49| `before_value` | JSON | Field values before the change (for Update events) | SOX, FINRA |50| `after_value` | JSON | Field values after the change (for Update events) | SOX, FINRA |51| `result` | enum | `success` \| `failure` \| `partial` | Completeness |52| `failure_reason` | string | If result = failure, why it failed | Debugging |53| `source_system` | string | Which system generated the event | Multi-system audit |54| `data_classification` | enum | `public` \| `internal` \| `confidential` \| `restricted` | Privacy |5556For events involving PII or PHI, also capture:57- `data_subject_id` — ID of the individual whose data was accessed58- `access_purpose` — Business purpose for accessing the data (required for GLBA/CCPA)5960## Step 3: Immutability Mechanisms6162The audit log must be tamper-evident and append-only. Choose one or more mechanisms based on client infrastructure:6364**Database-level:**65- Append-only table with no UPDATE or DELETE permissions for any application role66- Database trigger that blocks UPDATE/DELETE and alerts on attempt67- Row-level hash: `SHA-256(event_id + event_timestamp + actor_id + object_id + content_hash_of_all_fields)` stored in each row68- Periodic Merkle root calculation (batch of N records → root hash stored separately)6970**Storage-level:**71- Write-Once Read-Many (WORM) storage for log exports (AWS S3 Object Lock, Azure Blob immutability policy)72- Automated daily export to immutable cold storage with hash verification7374**Cryptographic chaining:**75- Each record contains `previous_record_hash` — SHA-256 of the previous record's full content76- Chain integrity verification: daily automated job validates the hash chain; alerts on break7778**Third-party:**79- Immutable audit log service (e.g., AWS CloudTrail, Azure Monitor, Splunk SIEM) as secondary sink80- Records written to primary DB and secondary immutable service simultaneously8182## Step 4: Retention Schedule8384| Event Category | Minimum Retention | Maximum Retention | Regulatory Citation |85|----------------|------------------|------------------|---------------------|86| Insurance policy transactions | 5 years post-policy expiration | 7 years | State DOI (varies; use most restrictive) |87| Insurance claims records | 5 years post-close | 10 years | State DOI claims regulations |88| Mortgage origination records | 3 years | 5 years | RESPA § 1024.9 |89| HMDA LAR data | 3 years | Permanent | Reg C § 1003.5 |90| BSA/AML suspicious activity | 5 years | Permanent | 31 CFR 1020.320 |91| FINRA communications | 3 years (first 2 easily accessible) | 6 years | FINRA Rule 4511 |92| SOX financial controls | 7 years | Permanent | SOX § 802 |93| Login/authentication logs | 1 year | 3 years | SOC 2 / general security |94| Failed authentication | 90 days | 1 year | Security best practice |95| System configuration changes | 3 years | 7 years | SOX ITGC |9697**Legal hold:** Any record subject to litigation hold must be retained until hold is released, regardless of standard retention period. Implement a legal hold flag that overrides automated deletion.9899## Step 5: Access Controls100101| Role | Permissions |102|------|-------------|103| Application services | INSERT only — no SELECT, UPDATE, DELETE |104| Compliance officer | SELECT with full field access, CSV export |105| Internal audit | SELECT with full field access, read-only |106| IT operations | SELECT on non-PII fields only; PII masked |107| Legal | SELECT with full access during litigation hold |108| Regulators (examination) | Read-only export of scoped date range |109| No role | DELETE or UPDATE (blocked at DB and application layer) |110111All access to the audit log itself must be logged in a separate meta-audit log (log of logs).112113## Step 6: Examination Query Patterns114115Design indexed queries for the most common regulatory examination scenarios:116117```sql118-- All actions by a specific user in a date range119SELECT * FROM audit_log120WHERE actor_id = :user_id121 AND event_timestamp BETWEEN :start_date AND :end_date122ORDER BY event_timestamp;123124-- All changes to a specific record125SELECT * FROM audit_log126WHERE object_type = :entity_type AND object_id = :record_id127ORDER BY event_timestamp;128129-- All failed authentication attempts130SELECT * FROM audit_log131WHERE event_code = 'AUTH.LOGIN.FAIL'132 AND event_timestamp >= :start_date133ORDER BY event_timestamp;134135-- All disclosures delivered (for TRID/ECOA examination)136SELECT * FROM audit_log137WHERE event_code IN ('DISC.LE.DELIVER', 'DISC.CD.DELIVER', 'DISC.ADVERSE.DELIVER')138 AND event_timestamp BETWEEN :start_date AND :end_date;139140-- Chain integrity verification141SELECT event_id, event_timestamp,142 SHA256(CONCAT(event_id, event_timestamp, actor_id, object_id, content)) AS computed_hash,143 stored_hash,144 (computed_hash = stored_hash) AS hash_valid145FROM audit_log146ORDER BY event_timestamp;147```148149## Output Format150151Deliver four artifacts:1521531. **Event Catalog Table** — All events with code, description, trigger, frequency, regulatory driver1542. **Data Schema** — Full field definition table with types, constraints, and regulatory basis1553. **Retention Matrix** — Retention schedule table with regulatory citations1564. **Access Control Specification** — Role permission matrix and meta-audit requirements