Use the default, non-deterministic encryption for Active Record attributes, and switch to deterministic: true only for columns you must look up by exact value, such as an email address. Deterministic mode makes equality queries possible but, per the Rails guide, makes cryptanalysis easier.
Definitions
Active Record Encryption lets you declare encrypted attributes in a model with encrypts. By default it is non-deterministic: encrypting the same value twice with the same key gives different ciphertexts. The guide says this improves security by making analysis of ciphertexts harder. Deterministic encryption generates initialization vectors in a deterministic way, so the same plaintext always yields the same ciphertext.
The guide says non-deterministic mode uses AES-GCM with a 256 bit key and a random initialization vector.
The trade in one table
| Property | Non-deterministic (default) | Deterministic |
|---|---|---|
| Same input, same output | No | Yes |
| Query with find_by or where | Not possible | Equality only |
| Pattern leakage | Low | Equal values are visible as equal |
| Guide recommendation | Recommended for all data unless querying | Use only when you must query |
In deterministic mode, someone with database access can see which rows share the same value, even without decrypting. For an email column that may be acceptable. For a health status or a category code with few values, it can reveal a lot.
How to decide
- List the sensitive columns.
- For each, ask whether you ever search by exact value.
- If not, use plain
encrypts :column. - If yes, consider a different design first, such as storing a separate keyed hash for lookup, and decide whether equality leakage is acceptable.
- Use deterministic mode only on high cardinality values, like emails, where equal values already reveal little.
- Document the choice next to the model.
class Author < ApplicationRecord
encrypts :bio
encrypts :email, deterministic: true
end
Keys and configuration
The guide shows keys for the primary, deterministic and key derivation salt values set in credentials or from environment variables. Treat them like any other master secret: separate per environment, never committed in plain text, and recoverable by more than one person. Losing them means losing the data.
Encrypted attributes are also filtered in console output, which the guide shows as a filtered value, and the guide mentions parameter filtering for related logging. Check logs yourself anyway.
What encryption at the model layer does not do
It protects data against someone reading the database or a backup. It does not protect against a user who can run code in your app, since the app decrypts values to use them. It also does not replace access control.
Planning for key loss and change
Encrypted data is only as recoverable as its keys. Store them in at least two protected places, document who can retrieve them, and test a restore in a non production environment. If you ever need to change keys, plan the re-encryption as a migration with a rollback, and run it on a copy first. Also remember that adding encryption to an existing column needs a data migration for the old plaintext rows.
Quick check
Can I query a non-deterministic column?
Not by value. The guide says queries like a where clause on the plaintext are not possible, because the stored ciphertext differs each time.
Is deterministic encryption unsafe?
It is encrypted but weaker. The guide recommends non-deterministic for all data unless you need to query by it.
Safeguard's compliance and evidence automation can help document data protection choices like this. A free scan is at gold.safeguard.sh/scan.
Sources
Last reviewed: 19 October 2026.