Auto Redaction
Sensitive fields and headers are masked before storage.
Go Audit has two redaction paths with different semantics. Data audit records drop excluded fields entirely; API call records mask sensitive values with a placeholder so you can see that a secret was present and what shape it had.
Data Audit: Fields Are Dropped
Fields listed in DataAudit.ExcludeFields are removed from both
old_values and new_values before the audit row is written:
DataAudit: audit.DataAuditConfig{
ExcludeFields: []string{"password", "token", "api_key"},
}If a user's password changes, the audit row for that update will
simply not mention password at all. If password was the only
field that changed, the entire UPDATE record is suppressed.
Matching is case-sensitive on the map key (which is normally the DB column name provided by the ORM adapter).
DataAudit.ExcludeEntities is the coarser version — skip whole
tables:
DataAudit: audit.DataAuditConfig{
ExcludeEntities: []string{"sessions", "cache_entries"},
}API Audit: Values Are Masked
For outbound HTTP calls, two config fields cover headers and bodies:
APIAudit: audit.APIAuditConfig{
RedactHeaders: []string{"Authorization", "Cookie", "X-API-Key"},
RedactBodyFields: []string{"password", "card_number", "cvv"},
}RedactHeaders— case-insensitive header name match. Value is replaced with"***REDACTED***".RedactBodyFields— case-insensitive JSON key match at any depth in request and response bodies. Value is replaced with"***REDACTED***".
{
"request_headers": {
"Authorization": "***REDACTED***",
"Content-Type": "application/json"
},
"request_body": {
"customer": { "card_number": "***REDACTED***", "name": "Ada" }
}
}Why Different Strategies?
- Data audits are diffs. If a password changed but you'd still
store
"password": "***REDACTED***"on both sides of the diff, every single password change would create noisy entries that tell you nothing useful. Dropping the field keeps the trail clean. - API audits are forensic records of a wire-level interaction.
Seeing that a header/field existed matters — a masked
Authorizationheader tells you the call was authenticated, and"card_number": "***REDACTED***"tells you a payment payload was sent. The shape of the call is the record.
Compliance
This design covers typical PCI/HIPAA requirements for not persisting raw secrets. Verify with your own security review for your specific regulatory obligations, and remember that audit metadata and transaction IDs themselves can be sensitive in some contexts.