Encrypting Data in Ruby on Rails 7 with Active Record Encryption

In this article, we’re diving into the world of encrypting data at the application level with Active Record Encryption, one of the nifty features baked into Rails 7.

So, what’s the scoop on Active Record Encryption? It’s like a superhero cape for sensitive information in our app — think passport numbers, driver’s licenses, social security digits, you name it.

The cool part? Active Record Encryption plays it smooth by encrypting attributes before saving them to the database and effortlessly decrypting them upon retrieval. Your app gets to handle data like it’s just another Tuesday, but behind the scenes, it’s all encrypted goodness. Now, you might wonder, if you’ve already encrypted your database, why add this extra layer at the app level?

Active Record Encryption plays it smooth by encrypting attributes before saving them to the database and effortlessly decrypting them upon retrieval.

Well, there are a bunch of reasons, but the big guns are:

  1. Extra Security Layer: Encrypting sensitive data adds an extra security blanket. Even if a sneaky intruder gets their hands on your database, a backup, or your app’s logs, decoding the info is a no-go.
  2. Developer Shield: Encryption stops us, developers, from accidentally exposing sensitive user data in the app’s logs. No more oops moments!

And here’s the kicker — by rocking Active Record Encryption, we’re setting ground rules in our code, making it crystal clear what counts as sensitive info in our app. It’s teamwork-friendly, creating solid processes and conventions 🚀

How does this “magic” work?

Well, to get in on the action, you gotta configure the encryption keys — key_derivation_saltprimary_key, and deterministic_key — in your credentials file (crack it open with the rails credentials:editcommand).

To whip up those keys, just fire up your console and throw in this command:

bin/rails db:encryption:init

# That'll cough up key-value pairs like the ones below. Copy and
# paste these into your credentials file.

active_record_encryption:
primary_key: one_primary_key
deterministic_key: one_deterministic_key
key_derivation_salt: one_key_derivation_salt

Once you’ve got those keys in your toolbox, it’s time to roll with application-level attribute encryption. Let’s dive into an example by enabling encryption for the driver_license attribute in the User model:

# app/models/user.rb

class User < ApplicationRecord
encrypts :driver_license
end

With this setup, whenever we create a new user, we’ll spot the encrypted value for driver_license in the table. However, when we fire up a query using ActiveRecord, fear not – we’ll get back the unencrypted value.

You can see this in action by keeping an eye on the Rails console when creating a user and retrieving it from the database:

# rails console
>> User.create name: "Fabian Show", driver_license: "890AC9921"
TRANSACTION (0.1ms) begin transaction
User Create (0.4ms) INSERT INTO "users" ("name", "driver_license") VALUES (?, ?) [["name", "Fabian Show"], ["driver_license", "{\"p\":\"aOKC5WCsykZ=\",\"h\":{\"iv\":\"aLlEyI5LopPb0gxQ\",\"at\":\"R50hGkso0XbI9d9Lo-p+lq==\"}}"]]
TRANSACTION (1.2ms) commit transaction

>> User.last
=> #<User id: 1, name: "Fabian Show", driver_license: "890AC9921", ...>

All of this magic happens because Ruby on Rails 7 taps into the power of the EncryptableRecord concern to handle the encryption and decryption when saving or fetching values from the database. If you’re itching for more details on Active Record Encryption, we recommend peeking into the official documentation for a deeper dive.

Happy coding! ☺️