Class: DataRedactor::Integrations::Rack

Inherits:
Object
  • Object
show all
Defined in:
lib/data_redactor/integrations/rack.rb

Overview

Rack middleware that scrubs sensitive data from selectable surfaces of the response (and request headers, for downstream loggers to see scrubbed values).

### Surfaces

  • ‘:body` — wraps the response body so emitted bytes pass through DataRedactor.redact before reaching the client. Drops the `Content-Length` header (the redacted body may have a different byte length, and recomputing requires buffering).

  • ‘:headers` — scrubs response headers in place. Sensitive request headers (`Authorization`, `Cookie`, `X-Api-Key`, etc.) are redacted in the env hash so any downstream middleware that logs them sees scrubbed values.

Examples:

Both surfaces (default)

use DataRedactor::Integrations::Rack, scrub: [:body, :headers]

Headers only — leave the response body untouched

use DataRedactor::Integrations::Rack, scrub: [:headers]

Constant Summary collapse

DEFAULT_SCRUB =
[:body, :headers].freeze
SENSITIVE_REQUEST_HEADERS =
%w[
  HTTP_AUTHORIZATION
  HTTP_PROXY_AUTHORIZATION
  HTTP_COOKIE
  HTTP_X_API_KEY
  HTTP_X_AUTH_TOKEN
  HTTP_X_ACCESS_TOKEN
].freeze
SENSITIVE_RESPONSE_HEADERS =
%w[
  Set-Cookie
  Authorization
  X-Api-Key
  X-Auth-Token
  X-Access-Token
].freeze

Instance Method Summary collapse

Constructor Details

#initialize(app, scrub: DEFAULT_SCRUB, only: nil, except: nil, placeholder: DataRedactor::PLACEHOLDER_DEFAULT) ⇒ Rack

Returns a new instance of Rack.

Parameters:

  • app (#call)

    the Rack app

  • scrub (Array<Symbol>) (defaults to: DEFAULT_SCRUB)

    which surfaces to redact. Subset of ‘[:body, :headers]`. Defaults to `[:body, :headers]`.

  • only (defaults to: nil)

    forwarded to DataRedactor.redact

  • except (defaults to: nil)

    forwarded to DataRedactor.redact

  • placeholder (defaults to: DataRedactor::PLACEHOLDER_DEFAULT)

    forwarded to DataRedactor.redact



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/data_redactor/integrations/rack.rb', line 51

def initialize(app, scrub: DEFAULT_SCRUB, only: nil, except: nil, placeholder: DataRedactor::PLACEHOLDER_DEFAULT)
  @app = app
  @scrub = Array(scrub).map(&:to_sym)
  unknown = @scrub - [:body, :headers]
  unless unknown.empty?
    raise ArgumentError, "unknown scrub surface(s) #{unknown.inspect}; valid: [:body, :headers]"
  end
  @only = only
  @except = except
  @placeholder = placeholder
end

Instance Method Details

#call(env) ⇒ Object



63
64
65
66
67
68
69
70
71
# File 'lib/data_redactor/integrations/rack.rb', line 63

def call(env)
  scrub_request_headers(env) if @scrub.include?(:headers)
  status, headers, body = @app.call(env)
  headers = scrub_response_headers(headers) if @scrub.include?(:headers)
  if @scrub.include?(:body)
    body, headers = wrap_body(body, headers)
  end
  [status, headers, body]
end