Module: Legion::Logging::Redactor

Defined in:
lib/legion/logging/redactor.rb

Constant Summary collapse

PATTERNS =
{
  ssn:            /\b\d{3}-\d{2}-\d{4}\b/,
  email:          /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/,
  phone:          /\b(?:\+1[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/,
  mrn:            /\bMRN[:\s]*\d{6,10}\b/i,
  dob:            %r{\bDOB[:\s]*\d{1,2}[/-]\d{1,2}[/-]\d{2,4}\b}i,
  credit_card:    /\b\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b/,
  vault_token:    /\bhvs\.[A-Za-z0-9_-]{20,}\b/,
  vault_lease_id: %r{\b[a-z_-]+/creds/[a-z_-]+/[A-Za-z0-9-]{36}\b},
  jwt:            /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/,
  vault_uri:      %r{vault://[^"',\]\x7d\s]+},
  lease_uri:      %r{lease://[^"',\]\x7d\s]+},
  bearer_token:   %r{Bearer\s+[A-Za-z0-9._~+/=-]{20,}}i
}.freeze
SENSITIVE_FIELDS =
%w[
  password
  secret
  token
  api_key
  access_key
  private_key
  public_key
  authorization
].freeze
SENSITIVE_SUFFIXES =
%w[token secret password passphrase credential credentials].freeze
SAFE_KEY_FIELDS =
%w[primary_key foreign_key sort_key partition_key routing_key].freeze
REDACTED =
'[REDACTED]'

Class Method Summary collapse

Class Method Details

.redact(event) ⇒ Object



37
38
39
40
41
42
43
# File 'lib/legion/logging/redactor.rb', line 37

def redact(event)
  return event unless event.is_a?(Hash)

  event.each_with_object({}) do |(key, value), result|
    result[key] = sensitive_field?(key) ? REDACTED : redact_value(value)
  end
end

.redact_string(str) ⇒ Object



54
55
56
57
58
# File 'lib/legion/logging/redactor.rb', line 54

def redact_string(str)
  result = str.dup
  all_patterns.each_value { |pattern| result.gsub!(pattern, REDACTED) }
  result
end

.redact_value(value) ⇒ Object



45
46
47
48
49
50
51
52
# File 'lib/legion/logging/redactor.rb', line 45

def redact_value(value)
  case value
  when String then redact_string(value)
  when Hash   then redact(value)
  when Array  then value.map { |v| redact_value(v) }
  else value
  end
end