sanitization

package
v1.3.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 26, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Overview

Package sanitization provides DD-005 compliant log sanitization utilities.

This package consolidates sanitization logic.

Migration Status (December 2025): - pkg/notification/sanitization/sanitizer.go → MIGRATED ✅ (uses this package) - pkg/gateway/middleware/log_sanitization.go → DELETED ✅ (migrated Dec 9, 2025)

All services MUST use this package for log sanitization to ensure: - Consistent redaction patterns across the codebase - DD-005 compliance (Observability Standards) - Security: No sensitive data in logs (CVSS 5.3)

Usage

For simple string sanitization:

sanitized := sanitization.SanitizeForLog(sensitiveData)
logger.Info("Processing request", "payload", sanitized)

For HTTP middleware:

router.Use(sanitization.NewLoggingMiddleware(logger))

For notification content:

sanitizer := sanitization.NewSanitizer()
clean, err := sanitizer.SanitizeWithFallback(content)

Patterns Covered

The sanitizer redacts the following sensitive patterns:

  • Passwords: password, passwd, pwd (JSON, URL, plain text)
  • API Keys: api_key, apikey, OpenAI (sk-*), AWS keys
  • Tokens: Bearer, GitHub (ghp_*), access_token, generic token
  • Secrets: secret, client_secret, credential
  • Database URLs: PostgreSQL, MySQL, MongoDB connection strings
  • Certificates: PEM certificates, private keys
  • Kubernetes: Secret data (base64 encoded)
  • HTTP Headers: Authorization, Bearer, X-API-Key

DD-005 Compliance

Authority: docs/architecture/decisions/DD-005-OBSERVABILITY-STANDARDS.md

Per DD-005 Lines 519-555:

"Sensitive data MUST be redacted before logging"
"Sensitive Fields (MUST be redacted): password, token, api_key, secret, authorization"

Business Requirements

  • BR-GATEWAY-078: Redact sensitive data from logs
  • BR-GATEWAY-079: Prevent information disclosure through logs
  • BR-NOT-055: Graceful degradation for sanitization failures
  • BR-STORAGE-XXX: Log sanitization (pending implementation)

Security

  • VULN-GATEWAY-004: Prevents sensitive data exposure in logs (CVSS 5.3)

Index

Constants

View Source
const (
	PathPlaceholderID   = ":id"   // For UUIDs and numeric IDs
	PathPlaceholderUUID = ":uuid" // Specifically for UUIDs
	PathPlaceholderNum  = ":num"  // Specifically for numeric IDs
)

Path placeholders for normalized segments

View Source
const RedactedPlaceholder = "[REDACTED]"

RedactedPlaceholder is the standard replacement for sensitive data. Use this constant for consistency across the codebase.

Variables

View Source
var SensitiveHeaderNames = []string{
	"authorization",
	"x-api-key",
	"x-auth-token",
	"x-access-token",
	"cookie",
	"set-cookie",
	"proxy-authorization",
	"www-authenticate",
	"bearer",
	"token",
	"password",
	"secret",
	"api_key",
	"apikey",
}

SensitiveHeaderNames contains header names that should always be redacted. Case-insensitive matching is used.

Functions

func AddSensitiveHeader

func AddSensitiveHeader(headerName string)

AddSensitiveHeader adds a custom header name to the sensitive list. Use this for service-specific headers that should be redacted.

Example:

sanitization.AddSensitiveHeader("x-custom-secret")

func IsHeaderSensitive

func IsHeaderSensitive(headerName string) bool

IsHeaderSensitive checks if a header name contains sensitive keywords. Uses case-insensitive matching against known sensitive header patterns.

func IsIDLikeSegment

func IsIDLikeSegment(segment string) bool

IsIDLikeSegment checks if a path segment looks like a dynamic ID. Useful for custom normalization logic.

func NormalizePath

func NormalizePath(path string) string

NormalizePath replaces dynamic path segments with placeholders. This prevents high-cardinality metrics from overwhelming Prometheus.

DD-005 Compliance: Per lines 689-710, path normalization is MANDATORY for all services exposing HTTP metrics.

Example:

NormalizePath("/api/v1/users/123/orders/abc-def-123")
// Returns: "/api/v1/users/:id/orders/:id"

NormalizePath("/api/v1/events/550e8400-e29b-41d4-a716-446655440000")
// Returns: "/api/v1/events/:id"

func NormalizePathWithPlaceholder

func NormalizePathWithPlaceholder(path string) string

NormalizePathWithPlaceholder normalizes using specific placeholder types. Use this when you need to distinguish between UUIDs and numeric IDs.

Example:

NormalizePathWithPlaceholder("/users/123")
// Returns: "/users/:num"

NormalizePathWithPlaceholder("/users/550e8400-e29b-41d4-a716-446655440000")
// Returns: "/users/:uuid"

func SanitizeForLog

func SanitizeForLog(data string) string

SanitizeForLog is a convenience function for quick sanitization. Use this for one-off sanitization without creating a Sanitizer instance.

Example:

logger.Info("Request", "body", sanitization.SanitizeForLog(body))

func SanitizeHeaders

func SanitizeHeaders(headers http.Header) string

SanitizeHeaders redacts sensitive information from HTTP headers. Returns a string representation suitable for logging.

Example:

headers := http.Header{"Authorization": {"Bearer secret"}, "Content-Type": {"application/json"}}
sanitized := sanitization.SanitizeHeaders(headers)
// Returns: "Authorization: [REDACTED], Content-Type: application/json"

func SanitizeHeadersToMap

func SanitizeHeadersToMap(headers http.Header) map[string][]string

SanitizeHeadersToMap returns a sanitized copy of headers as a map. Useful when you need to preserve the map structure.

Types

type Rule

type Rule struct {
	Name        string         // Human-readable name for debugging
	Pattern     *regexp.Regexp // Regex pattern to match sensitive data
	Replacement string         // Replacement string (may use capture groups)
	Description string         // Description of what this rule redacts
}

Rule defines a pattern-based sanitization rule. Each rule matches a specific type of sensitive data and replaces it.

func DefaultRules

func DefaultRules() []*Rule

DefaultRules returns the comprehensive set of sanitization rules. These cover the most common sensitive data patterns.

IMPORTANT: Pattern order matters! Container patterns (generatorURL, annotations) must come FIRST to prevent sub-patterns from corrupting larger structures.

type Sanitizer

type Sanitizer struct {
	// contains filtered or unexported fields
}

Sanitizer provides configurable log sanitization. Use NewSanitizer() to create with default patterns, or NewSanitizerWithRules() for custom patterns.

func NewSanitizer

func NewSanitizer() *Sanitizer

NewSanitizer creates a sanitizer with comprehensive default patterns. Covers passwords, API keys, tokens, database URLs, certificates, etc.

func NewSanitizerWithRules

func NewSanitizerWithRules(rules []*Rule) *Sanitizer

NewSanitizerWithRules creates a sanitizer with custom rules. Use this when you need service-specific patterns.

func (*Sanitizer) SafeFallback

func (s *Sanitizer) SafeFallback(content string) string

SafeFallback provides simple string-based sanitization without regex. Used when regex engine fails or for ultra-safe processing. Uses simple string matching which cannot panic.

func (*Sanitizer) Sanitize

func (s *Sanitizer) Sanitize(content string) string

Sanitize applies all rules to redact sensitive data from content. Returns the sanitized content with sensitive data replaced.

Example:

s := sanitization.NewSanitizer()
clean := s.Sanitize(`{"password":"secret123"}`)
// Returns: `{"password":"[REDACTED]"}`

func (*Sanitizer) SanitizeWithFallback

func (s *Sanitizer) SanitizeWithFallback(content string) (string, error)

SanitizeWithFallback sanitizes content with automatic fallback on errors. If regex processing fails (e.g., panic), falls back to simple string matching.

This implements graceful degradation per BR-NOT-055: - When: Redaction logic error, malformed data - Action: Log error, use fallback sanitization - Recovery: Automatic (degraded but safe)

Returns the sanitized content and any error that occurred.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL