PGCrypto for ActiveRecord 🆊

PostgreSQL PGCrypto support for ActiveRecord models.

Don't roll your own crypto

About

The goal of this project is to provide a simple and efficient encryption support for your application records.

Main goals:

  • No magic please
  • No DSLs please
  • Less code, less maintenance
  • Good docs and test coverage
  • Keep it up-to-date (or at least tell people this is no longer maintained)

The available features include:

  • PostgreSQL pgcrypto native symmetric encryption using the attribute serialization API and Arel API.
  • Logger support for sensitive data query obfuscation.

A bit of history...

The project was born after trying out crypt_keeper and having to deal with the broken support for PostgreSQL where the stored data would be invalid for native SQL functions.

I would like to thank Justin for his work, but I decided to move away from the original work for arguably subjective reasons and the critical importance of this functionality in my projects.

Installation

Add this line to your application's Gemfile:

gem 'active_record-pgcrypto'

And then execute:

$ bundle

Or install it yourself as:

$ gem install active_record-pgcrypto

Usage

To start using it with ActiveRecord/Rails, add this to an initializer and configure your keys:

# config/initializers/pgcrypto.rb
require 'active_record/pgcrypto'
# Replace the default environment variable name with your own value/key.
ActiveRecord::PGCrypto::SymmetricCoder.pgcrypto_key = ENV['PGCRYPTO_SYM_KEY']

Now enable the coder for your model attributes:

class MyModel < ActiveRecord::Base
  serialize(:email, ActiveRecord::PGCrypto::SymmetricCoder)
end

NOTE: In order for the encrypted data to be store the column must be of type binary.

The coder provides a simple API to help you provide search support by leveraging the Arel API:

class MyModel < ActiveRecord::Base
  serialize(:email, ActiveRecord::PGCrypto::SymmetricCoder)

  def self.decrypted_email
    ActiveRecord::PGCrypto::SymmetricCoder
      .decrypted_arel_text(arel_table[:email])
  end
end

Now you can use add it to your ActiveRecord::Base#where queries:

MyModel.where(MyModel.decrypted_email.matches('keyword%'))

Development

Build the Docker image first:

docker build -f Dockerfile -t active_record-pgcrypto/ci ./`

Now you can run the tests:

docker run -v `pwd`:/gem -it active_record-pgcrypto/ci

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/stas/active_record-pgcrypto. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

License

The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting with this project codebase, issue tracker, chat rooms and mailing list is expected to follow the code of conduct.