-
Notifications
You must be signed in to change notification settings - Fork 1
Integration Guides
Optional adapters for Logger, Rails, Rack, and the Claude/OpenAI SDKs. None are
loaded automatically — require 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/.
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.
# 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.
# config.ru
require "data_redactor/integrations/rack"
use DataRedactor::Integrations::Rack, scrub: [:body, :headers]
run MyAppscrub: selects which surfaces to redact (default [:body, :headers]):
-
:body— buffers the response body, redacts it, returns it as a single chunk. DropsContent-Lengthso 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) usescrub: [:headers]and lean on the Logger formatter for application logs.
Runnable: examples/rack_middleware.rb.
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.
Guides
Reference
Elsewhere