ruby 34 lines · 7 steps

Redacting secrets in Ruby object output

A credentials class that scrubs sensitive fields from every serialization path so secrets never leak into logs or JSON.

Explained by highlit
1class Credentials
2 SENSITIVE = %i[password api_key secret_token access_key].freeze
3 REDACTED = "[REDACTED]".freeze
4 
5 attr_reader :username, :password, :api_key, :secret_token, :access_key
6 
7 def initialize(username:, password:, api_key:, secret_token:, access_key:)
8 @username = username
9 @password = password
10 @api_key = api_key
11 @secret_token = secret_token
12 @access_key = access_key
13 end
14 
15 def to_h
16 instance_variables.each_with_object({}) do |ivar, memo|
17 name = ivar.to_s.delete_prefix("@").to_sym
18 memo[name] = SENSITIVE.include?(name) ? REDACTED : instance_variable_get(ivar)
19 end
20 end
21 
22 def inspect
23 fields = to_h.map { |name, value| "#{name}=#{value.inspect}" }.join(", ")
24 "#<#{self.class.name} #{fields}>"
25 end
26 
27 def to_s
28 inspect
29 end
30 
31 def as_json(*)
32 to_h
33 end
34end
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Centralize redaction in one method so every output path stays consistent by definition.
  2. 2Overriding inspect and to_s prevents secrets from leaking into logs and error traces.
  3. 3A frozen list of sensitive keys makes the redaction policy explicit and easy to audit.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Redacting secrets in Ruby object output — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code