Skip to content

Integration Guides

daniele frisanco edited this page Jul 5, 2026 · 1 revision

Integration Guides

Optional adapters for Logger, Rails, Rack, and the Claude/OpenAI SDKs. None are loaded automaticallyrequire only what you use, and the gem adds zero runtime dependencies. Every adapter forwards only: / except: / placeholder: to DataRedactor.redact.

Using RubyLLM? It has its own page — see ⭐ RubyLLM Integration. It's the recommended path for scrubbing anything headed to an LLM, with a transparent install! mode.

Each adapter also has a runnable script under examples/.

Logger formatter

Drop-in Logger::Formatter replacement that scrubs every emitted line.

require "data_redactor/integrations/logger"

logger = Logger.new($stdout)
logger.formatter = DataRedactor::Integrations::Logger.new
logger.info("Auth failed for alice@example.com")
# => I, [...] -- : Auth failed for [REDACTED]

Wraps an inner formatter (defaults to Logger::Formatter), so it composes with structured loggers. Exceptions and arbitrary objects are scrubbed too — the wrapped object is passed unchanged to the inner formatter (the exception cause chain is preserved); only the rendered string is redacted.

Runnable: examples/logger.rb, and examples/rails_logger.rb showing Logger + Rack together.

Rails filter_parameters

# config/initializers/filter_parameter_logging.rb
require "data_redactor/integrations/rails"

Rails.application.config.filter_parameters += [
  DataRedactor::Integrations::Rails.filter
]

Returns a (key, value) proc compatible with Rails' parameter filter. String values are mutated in place via String#replace so Rails sees the redacted value; non-strings are left alone. Runnable: examples/rails_filter.rb.

Rack middleware

# config.ru
require "data_redactor/integrations/rack"

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

scrub: selects which surfaces to redact (default [:body, :headers]):

  • :body — buffers the response body, redacts it, returns it as a single chunk. Drops Content-Length so the server recomputes it (the redacted body may differ in byte length).
  • :headers — scrubs sensitive response headers (Set-Cookie, Authorization, X-Api-Key, X-Auth-Token, X-Access-Token) in place, and sensitive request headers (HTTP_AUTHORIZATION, HTTP_PROXY_AUTHORIZATION, HTTP_COOKIE, HTTP_X_API_KEY, HTTP_X_AUTH_TOKEN, HTTP_X_ACCESS_TOKEN) in the env hash, so downstream middleware that logs them sees redacted values.

Pass a subset (e.g. scrub: [:headers]) to opt out of body wrapping. Unknown surfaces raise ArgumentError at boot.

⚠️ Body wrapping buffers the whole response into memory before scanning. For streaming endpoints (SSE, large downloads, Rack::Hijack) use scrub: [:headers] and lean on the Logger formatter for application logs.

Runnable: examples/rack_middleware.rb.

Claude / OpenAI SDK payloads

Sanitize LLM message payloads before they leave the process, and scrub responses before logging/storing. Both adapters operate on plain Ruby Hashes/Arrays (String or Symbol keys), so they work with the anthropic/openai gems, a raw HTTP client, or parsed JSON — no runtime dependency on any SDK. They return a deep copy and never mutate your input.

require "data_redactor/integrations/claude"

safe_messages = DataRedactor::Integrations::Claude.redact_messages(messages)
client.messages.create(model: "claude-opus-4-8", max_tokens: 1024, messages: safe_messages)

safe_response = DataRedactor::Integrations::Claude.redact_response(response)
require "data_redactor/integrations/openai"

safe_messages = DataRedactor::Integrations::OpenAI.redact_messages(messages)
client.chat(parameters: { model: "gpt-4o", messages: safe_messages })

safe_response = DataRedactor::Integrations::OpenAI.redact_response(response)

content may be a plain String or an array of content blocks ({ type: "text", text: "…" }) — only the text of text blocks is redacted; image and other block types pass through untouched. For Claude, a top-level system: String is redacted; for OpenAI, a { role: "system" } message is redacted like any other. Pass a bare messages array or the whole request Hash.

These SDK helpers are per-call. For automatic redaction across every provider request — including tool results an agent feeds back — prefer ⭐ RubyLLM Integration.

See also

Clone this wiki locally