How to keep Ruby object instance variables hidden from view in irb or logs?
Question
I am making a gem to wrap an API. The service requires a few login parameters so I made a Connection class to initialize by passing in all login values, and storing with instance variables. One of these values, @secret_access_key
is secret, obviously. It is not readable within the app. But while testing the gem in irb, I see the secret key displayed along with all other instance variables when the object is returned.
mws = MWS::Connection.new :access_key => '1', :secret_access_key => 'SECRET!!!', :merchant_id => '3', :marketplace_id => '4'
=> #<MWS::Connection:0x007fbd22acef40 @access_key="1", @merchant_id="3", @marketplace_id="4", @secret_access_key="SECRET!!!">
I am paranoid that the secret key will show up in Heroku logs, app error messages, or whatever else.
Should I be worrying? If so, what's the best way to store or hide this information?
Also, I am using httparty gem to manage this, is there something better I can do with that gem?
Solution
You could use this workaround:
class MWS::Connection
def inspect
"#<MWS::Connection:#{object_id}>"
end
end
Of course the secret key will still be accessible, but it shouldn't show up in any logs now:
mws = MWS::Connection.new :access_key => '1', :secret_access_key => 'SECRET!!!', :merchant_id => '3', :marketplace_id => '4'
# => #<MWS::Connection:0x007fbd22acef40>
mws.instance_variable_get(:@secret_access_key) # => 'SECRET!!!'
OTHER TIPS
class MWS::Connection
def initalize(opts)
...
@secret_access_key = Cypher.encypher(opts[:secret_access_key]) if opts[:secret_access_key]
end
def secret_access_key
Cypher.decypher @secret_access_key
end
end
class Cypher
def self.encypher(str)
str + 'fancy_encryption_protocol'
end
def self.decypher(str)
str.sub 'fancy_encryption_protocol$', ''
end
end