Gem Version Build Status

Mask ActiveRecord/Mongoid data with ease!


This gem is intended to mask sensitive data so that production database dumps can be used in staging or test environments. It works with Rails 4+ and modern Rubies. It supports Active Record and Mongoid models.

Getting started


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

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
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?

The ActiveRecord’s ::default_scope method has no effect on masking. All table records are updated, provided that :if and :unless filters allow that. For example, if you’re using a Paranoia[] gem to soft-delete your data, records marked as deleted will be masked as well.

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.


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.


attr_masker :first_name
attr_masker :last_name, :masker =>

Would set both first_name and last_name attributes to "(redacted)".


Replaces characters with some masker string (single asterisk by default). Can be initialized with options.

Name Default Description



Replacement string, can be empty.



When true, only alphanumeric charaters are replaced.


rm = "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 which db: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


attr_encrypted for the initial code structure