Config change logs (fee schedules, rates) audit-trailed
Why it matters
Fee schedules and interest rate changes are decisions that directly affect customer balances — and they are exactly the kind of discretionary administrative action that regulators and auditors scrutinize most carefully. SOX §404 requires that internal controls over financial reporting extend to the processes that determine what rates and fees are applied; an admin who can change a fee schedule without leaving a before/after record defeats that control. NIST 800-53 AU-2 requires auditing of configuration changes. PCI-DSS 4.0 Req-10.2.1.5 explicitly requires logging of changes to identification and authentication mechanisms as well as to system configurations. CWE-778 (Insufficient Logging) applies directly. Without a config_change_logs record that captures who changed the fee, from what value to what value, and when, there is no way to reconstruct whether a customer was charged the correct rate.
Severity rationale
Low because config-change logging is a detective control — its absence enables undetected rate manipulation but requires a second failure (the admin using the ungated path maliciously) to result in direct harm.
Remediation
Create a config_change_logs table and write a record before every config mutation in src/app/api/admin/config/route.ts or src/services/config-audit.ts:
CREATE TABLE config_change_logs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
config_key VARCHAR(100) NOT NULL,
old_value JSONB NOT NULL,
new_value JSONB NOT NULL,
changed_by UUID NOT NULL REFERENCES users(id),
changed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
reason TEXT
);
async function updateFeeSchedule(
newSchedule: FeeSchedule, adminId: string, reason: string
) {
const current = await db('config').where({ key: 'fee_schedule' }).first();
await db('config_change_logs').insert({
config_key: 'fee_schedule',
old_value: JSON.stringify(current.value),
new_value: JSON.stringify(newSchedule),
changed_by: adminId,
reason
});
await db('config').where({ key: 'fee_schedule' }).update({ value: newSchedule });
}
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Financial Audit Trail Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-778 — Insufficient Logging
- nist:rev5 · AU-2 — Event Logging — configuration changes
- pci-dss:4.0 · Req 10.2.1.5 — Log all changes to identification and authentication mechanisms including configuration changes
- sox · Section 404 — Management Assessment of Internal Controls — change management logging
Taxons
History
- 2026-04-18·v1.0.0·Initial import from finserv-audit-trail·automated