Introduction
This gem is intended to mask sensitive data so that production database dumps can be used in staging or test environments. It works with Active Record 4+ and modern Rubies.
Getting started
Installation
Add attr_masker to your gemfile:
gem "attr_masker", github: "riboseinc/attr_masker"
Then install the gem:
bundle install
Basic usage
In your models, define attributes which should be masked:
class User
attr_masker :email, :first_name, :last_name
end
Then, when you want to mask the data, run the db:mask
Rake task in some
Rails environment other than production, for example:
bundle exec rake db:mask RAILS_ENV=staging
Warning
|
Data are destructively overwritten. Run rake db:mask with care!
|
Masking records selectively
You can use :if
and :unless
options to prevent some records from being
altered.
# evaluates given proc for each record, and the record is passed as a proc's
# argument
attr_masker :email :unless => ->(record) { ! record.tester_user? }
# calls #tester_user? method on each record
attr_masker :first_name, :if => :tester_user?
Using custom maskers
By default, data is maksed with AttrMasker::Maskers::SIMPLE
masker which
always returns "(redacted)"
string. But anything what responds to #call
can be used instead: a lambda, Method
instance, and more. You can specify it
by setting the :masker
option.
For instance, you may want to use ffaker or Well Read Faker to generate random replacement values:
require "ffaker"
attr_masker :first_name, :masker => ->(_hash) { FFaker::Name.first_name }
A hash is passed as an argument, which includes some information about the record being masked and the attribute value. It can be used to further customize masker’s behaviour.
Built-in maskers
Attr Masker comes with several built-in maskers.
AttrMasker::Maskers::SIMPLE
-
Simply replaces any value with the
"(redacted)"
. Only useful for columns containing textual data.This is a default masker. It is used when
:masker
option is unspecified.Example:
attr_masker :first_name attr_masker :last_name, :masker => AttrMasker::Maskers::SIMPLE
Would set both
first_name
andlast_name
attributes to"(redacted)"
. AttrMasker::Maskers::Replacing
-
Replaces characters with some masker string (single asterisk by default). Can be initialized with options.
Name Default Description replacement
"*"
Replacement string, can be empty.
alphanum_only
false
When true, only alphanumeric charaters are replaced.
Example:
rm = AttrMasker::Maskers::Replacing.new(character: "X", alphanum_only: true) attr_masker :phone, :masker => rm
Would mask "123-456-7890" as "XXX-XXX-XXXX".
Roadmap & TODOs
-
documentation
-
spec tests
-
Make the
Rails.env
(in whichdb:mask
could be run) configurable-
maybe by passing
ENV
vars
-
-
more masking options!
-
default scrambling algorithms?
-
structured text preserving algorithms
-
e.g., keeping an HTML snippet valid HTML, but with masked inner text
-
-
structured Object preserving algorithms
-
i.e. generalization of the above HTML scenario
-
-
-
I18n of the default
"(redacted)"
phrase -
…
Acknowledgements
attr_encrypted for the initial code structure