Active_record_encryption_deterministic_key
class User < ApplicationRecord # This uses the deterministic key to allow find_by lookups encrypts :email, deterministic: true end Use code with caution. Copied to clipboard
While convenient, deterministic encryption is inherently less secure than randomized encryption. The usage of active_record_encryption_deterministic_key requires a strict threat-model assessment.
In config/application.rb or an initializer:
| Risk | Explanation | |------|-------------| | | If the same plaintext repeats (e.g., "admin@example.com" in many rows), an attacker with DB access can guess values by frequency. | | Pattern leakage | Two identical emails → identical ciphertext. No semantic security. | | Key separation required | Must use different keys from non-deterministic mode. Rails does this automatically, but misconfiguration (same key for both) breaks security. | | No key rotation | Changing deterministic_key breaks all existing queries on deterministic columns (ciphertext changes). You must re-encrypt data. | | IV reuse risk | Rails uses a deterministic IV derived from the attribute name + key. This is safe only if the key is unique per column. If you reuse the same deterministic key across columns, identical values in different columns encrypt identically (bad). | active_record_encryption_deterministic_key
: Because it produces predictable output, it is more vulnerable to frequency analysis attacks. It should only be used for data that absolutely must be searchable.
Because GCM’s security degrades if an IV is reused with the same key, deterministic IVs are because the key is not shared across columns. Rails ensures each column gets a derived key from the deterministic_key + column name.
| Approach | When to use | |----------|--------------| | (Rails built-in via encrypts :email, index: true ) | Need security + querying, but can accept slower writes. | | PostgreSQL pgcrypto deterministic encryption | Need DB-level function support (but loses Rails key management). | | Application-level searchable encryption (e.g., CipherSweet) | High-security needs with advanced indexes. | | Don’t encrypt – use column-level permissions + Vault | When queryability is more important than at-rest encryption. | | | Pattern leakage | Two identical emails
: This key is typically stored in your encrypted credentials file ( bin/rails credentials:edit ) or set as an environment variable in production.
: It derives the encryption key used for attributes declared as deterministic: true in your ActiveRecord models.
# config/application.rb config.active_record.encryption.deterministic_key = Rails.application.credentials.active_record_encryption_deterministic_key | | Application-level searchable encryption (e.g.
When you define an encrypted attribute in Rails, you might see it used like this:
The active_record_encryption_deterministic_key serves as a bridge between strict cryptographic security and pragmatic database functionality. It allows Rails applications to encrypt sensitive data while maintaining the ability to query that data efficiently. However, this power comes with the cost of vulnerability to frequency analysis. Developers must treat the deterministic key with the highest level of secrecy and strictly limit its application to fields where the trade-off between queryability and privacy is acceptable.
