ActiveRecord encryption
This course covers ActiveRecord::Encryption, which encrypts values inside the Rails application, so a plain SELECT against the database returns ciphertext. It starts by comparing this with disk encryption at rest. It then generates keys with bin/rails db:encryption:init and stores them in credentials. The lessons show what encrypts writes to a column, why find_by returns nil on a default encrypted column, and how deterministic: true keeps a column queryable at a cost. They also cover migrating plain-text rows and what happens when the key is lost.
What you'll learn
- ✓How encryption in the Rails app differs from disk encryption at rest
- ✓Generating keys with bin/rails db:encryption:init and storing them in credentials
- ✓What encrypts stores in a column and why default encrypted columns can't be queried
- ✓Using deterministic: true and downcase: true for columns that need lookups
- ✓Migrating existing plain-text rows with support_unencrypted_data and find_each(&:encrypt)
- ✓Why a lost or changed key makes encrypted data unrecoverable
Why encrypt in the app, not just at rest
Every migrations course so far asked how tables relate to each other, how safe an operation is on a live table, or how to order several changes. This course asks something else: not how a column is shaped or related, but what's safe to store in it as plain text, and what changes once the answer is…
Read the full lesson free →Curriculum
7 lessonsWhy encrypt in the app, not just at rest
Compares disk encryption at rest with encryption inside the Rails app, using Partners::Inquiry as the running example.
Setup: db:encryption:init and credentials
Generates three keys with bin/rails db:encryption:init, stores them in credentials and explains the role of each.
encrypts, and the column that can't be queried
Shows the JSON ciphertext that encrypts stores and why a random IV makes find_by return nil.
deterministic: true: a column that stays queryable
Uses deterministic: true and downcase: true to keep find_by working, at the cost of revealing equal values.
support_unencrypted_data: migrating without downtime
Adds encryption to a column with plain-text rows using support_unencrypted_data, then finishes with find_each(&:encrypt).
Losing the key is losing the data
Shows that changing primary_key makes encrypted values unreadable, raising a Decryption error with no partial recovery.
Putting it together: choosing per column
Applies every lesson to Partners::Inquiry, deciding per column what to encrypt, how, and what to leave alone.