go-auditGo Audit
Features

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 Authorization header 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.

On this page