Module: Posthaste::Redaction
- Defined in:
- lib/posthaste/redaction.rb
Overview
Keeping the API key out of everything that can be printed.
A key is a bearer credential: whoever holds it can send mail from every
verified domain on the account. The places it escapes from are not the ones
people guard — nobody logs the key on purpose. In Ruby it escapes through
the DEFAULT #inspect, which prints every instance variable, and a lot of
things call #inspect on your behalf:
* `p object`, and the console echoing a return value
* a `binding.irb` session pasted into a ticket
* Rails' exception page, which inspects the delivery method
* an error reporter (Sentry, Bugsnag, Honeybadger) capturing locals and
shipping them to a third party
So every object in this gem that can reach the key defines its own
#inspect, and every string built for a human goes through redact first.
Constant Summary collapse
- REDACTED =
'***redacted***'- PREFIX =
ph_live_…/ph_test_…. The prefix is not secret — it is printed in the dashboard beside every key — and it is the one piece that helps somebody staring at a 401 work out that they pasted the test key into production. /\Aph_(?:live|test)_/- KEY_SHAPED =
Anything key-shaped, wherever it turns up. Used for text this gem did not build itself — a server message that echoed the credential back, a transport error that quoted the request line — where there is no key to compare against.
/ph_(?:live|test)_[A-Za-z0-9_-]{8,}/
Class Method Summary collapse
-
.describe_key(api_key) ⇒ Object
A label for a key that cannot be turned back into the key.
-
.redact(text, api_key = nil) ⇒ Object
Remove the key from a string meant for a human.
Class Method Details
.describe_key(api_key) ⇒ Object
A label for a key that cannot be turned back into the key.
Deliberately NOT the usual "last four characters" convention. Four characters of a token this size is not enough to authenticate with, but it is enough to confirm a guess, and the thing it is normally used for — telling two keys apart — is served just as well by the environment prefix without narrowing the search space at all.
43 44 45 46 47 48 |
# File 'lib/posthaste/redaction.rb', line 43 def describe_key(api_key) return '(none)' if api_key.nil? || api_key.to_s.empty? match = PREFIX.match(api_key.to_s) "#{match ? match[0] : ''}#{REDACTED}" end |
.redact(text, api_key = nil) ⇒ Object
Remove the key from a string meant for a human.
Two passes on purpose. The first removes this client's own key, which catches it however short or oddly formatted it is. The second removes anything key-shaped, which catches a DIFFERENT account's key echoed back by a server or quoted by a library underneath us.
56 57 58 59 60 |
# File 'lib/posthaste/redaction.rb', line 56 def redact(text, api_key = nil) out = text.to_s out = out.gsub(api_key.to_s, REDACTED) if api_key && !api_key.to_s.empty? out.gsub(KEY_SHAPED, REDACTED) end |