Module: Alplus::Scrubber
- Defined in:
- lib/alplus/scrubber.rb
Overview
Default PII scrubbing applied to every captured item BEFORE
config.before_send runs (mirrors Sentry's built-in data scrubber).
Deep-walks context/contexts/tags/user (nested hashes and
arrays) and replaces any value whose key matches config.scrub_fields
(case-insensitive substring match, so "user_password" is caught by
the "password" entry) with "[FILTERED]".
Runs against the already-built wire item hash (post Envelope.*_item),
not the raw call-site args -- one scrub point regardless of whether the
value came from an explicit context:/tags:/user: argument or the
ambient Scope.
Constant Summary collapse
- DEFAULT_SCRUB_FIELDS =
%w[ password passwd secret token authorization api_key apikey access_token cookie csrf ssn credit_card card_number ].freeze
- REDACTED =
"[FILTERED]"- SCRUBBED_KEYS =
breadcrumbsis included so structured secrets in a crumb'sdatahash (and any secret-keyed value an integration adds) are redacted. A crumb's free-textmessageis NOT value-scrubbed -- key-based scrubbing cannot see into an arbitrary string, same as Sentry. Do not put a raw secret in a breadcrumb message. %i[context contexts tags user breadcrumbs].freeze
Class Method Summary collapse
- .deep_scrub(value, fields) ⇒ Object
-
.scrub(item, fields) ⇒ Object
Returns a new item hash with sensitive values redacted.
- .sensitive_key?(key, fields) ⇒ Boolean
Class Method Details
.deep_scrub(value, fields) ⇒ Object
49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/alplus/scrubber.rb', line 49 def deep_scrub(value, fields) case value when Hash value.each_with_object({}) do |(key, val), out| out[key] = sensitive_key?(key, fields) ? REDACTED : deep_scrub(val, fields) end when Array value.map { |v| deep_scrub(v, fields) } else value end end |
.scrub(item, fields) ⇒ Object
Returns a new item hash with sensitive values redacted. Never raises: an internal error returns the item unscrubbed rather than drop a real event over a scrubbing bug -- capture must not be less reliable than scrubbing is broken.
35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/alplus/scrubber.rb', line 35 def scrub(item, fields) return item if fields.nil? || fields.empty? normalized_fields = fields.map { |f| f.to_s.downcase } scrubbed = SCRUBBED_KEYS.each_with_object({}) do |key, out| next unless item.key?(key) out[key] = deep_scrub(item[key], normalized_fields) end item.merge(scrubbed) rescue StandardError item end |
.sensitive_key?(key, fields) ⇒ Boolean
62 63 64 65 |
# File 'lib/alplus/scrubber.rb', line 62 def sensitive_key?(key, fields) normalized_key = key.to_s.downcase fields.any? { |field| normalized_key.include?(field) } end |