createAuditEntry now deep-walks before/after/metadata and replaces
values of password, newPassword, currentPassword, passwordHash, token,
accessToken, refreshToken, sessionToken, apiKey, authorization, cookie,
secret, totpSecret, backupCode(s) with "[REDACTED]" before the JSONB
write.
The pino logger already redacts these paths for stdout (see
lib/logger.ts), but DB writes had no equivalent guard — the AI chat
loop at assistant-chat-loop.ts:265 blindly stores parsedArgs from tool
calls (e.g. set_user_password, create_user) into the AuditLog table.
Matching is case-insensitive; nested objects and arrays are recursed to
a depth of 8. Diffs are computed post-redaction so UPDATE entries that
only changed a sensitive field are correctly collapsed to no-op.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>