* Make sure active record encryption configuration happens after initializers have run
Co-authored-by: Cadu Ribeiro <mail@cadu.dev>
* Add a new option to support previous data encrypted non-deterministically with a hash digest of SHA1
There is currently a problem with Active Record encryption for users updating from 7.0 to 7.1 Before
#44873, data encrypted with non-deterministic encryption was always using SHA-1. The reason is that
`ActiveSupport::KeyGenerator.hash_digest_class` is set in an after_initialize block in the railtie config,
but encryption config was running before that, so it was effectively using the previous default SHA1. That
means that existing users are using SHA256 for non deterministic encryption, and SHA1 for deterministic
encryption.
This adds a new option `use_sha1_digest_for_non_deterministic_data` that
users can enable to support for SHA1 and SHA256 when decrypting existing data.
* Set a default value of true for `support_sha1_for_non_deterministic_encryption` and proper initializer values.
We want to enable the flag existing versions (< 7.1), and we want it to be false moving by
default moving forward.
* Make sure the system to auto-filter params supports different initialization orders
This reworks the system to auto-filter params so that it works when encrypted
attributes are declared before the encryption configuration logic runs.
Co-authored-by: Cadu Ribeiro <mail@cadu.dev>
---------
Co-authored-by: Cadu Ribeiro <mail@cadu.dev>
This is a follow up to rails#47186, this time for all markdown content.
[markdownlint](https://github.com/markdownlint/markdownlint) is an excellent tool, and I've found it very useful for finding issues in the guides.
Many of the rules are common style issues I'm correcting on PRs, so it will be nice to have that automated.
We should also be able to use the same config with our editors, so that errors show up in real-time 🙏 and will update the contributing docs once this gets merged with how to debug and use mdl appropriately.
Before, it was using the configured by Rails. Having a mechanism to configure it
for Active Record encryption makes sense to prevent problems with encrypted content
when the default in Rails changes.
Additionally, there was a bug making AR encryption use the older SHA1 before
`ActiveSupport.hash_digest_class` got initialized to SHA256. This bug was exposed
by https://github.com/rails/rails/pull/44540. We will now set SHA256 as the standard
for 7.1+, and SHA1 for previous versions.
YAML has quite a bit of footguns, as such it's desirable
to be able to substitute it for something else or even
simply to force users to define a serializer explictly for
every serialized columns.
For example, when encrypting `Person#name` it will add `person.name` as a filter
parameter, instead of just `name`. This prevents unintended filtering of parameters
with a matching name in other models.
Closes https://github.com/rails/rails/issues/44330
This splits the table of `config.active_record.encryption.*` settings
into individual linkable sections, similar to the Configuration guide.
This also bumps up the advice about using credentials, adds a few
backticks in the appropriate spots, and fixes a link which always
pointed to the latest version of the Configuration guide.
I read quite a bit of this code the other day, so it made sense for me
to read through the guide as well.
While reading through it, I looked for opportunities to increase clarity
and simplify things. I also fixed a few typos!
Co-authored-by: Gannon McGibbon <gannon@hey.com>
* Fix: re-encrypting will preserve case when ignore_case is used
The implementation was outdated in relation to the new approach where we
override accessors.
* Add support for exists?(...) when querying encrypted attributes
* Add a new option to force encoding for deterministic attributes
Different encodings result in different ciphertexts. For
deterministically encrypted attributes, this can result in having
attributes with the same value that fails to satisfy uniqueness
constraints due to having different encodings.
This adds a new option `forced_encoding_for_deterministic_encryption:`
that will be UTF-8 by default. User can disabled this new behavior by
setting the option to nil.
* Add changelog entry
This implements several changes to encourage deterministic encryption to
remain unchanged. The main motivation is letting you define unique
indexes on deterministically-encrypted columns:
- By default, deterministic encryption will always use the oldest
encryption scheme to encrypt new data, when there are many.
- You can skip this default behavior and make it always use the current
encryption scheme with:
```ruby
deterministic: { fixed: false } # using this should be a rare need
```
- Deterministic encryption still supports previous encryption schemes
normally. So they will be used to add additional values to queries, for
example.
- You can't rotate deterministic encryption keys anymore. We can add
support for that in the future.
This makes for reasonable defaults:
- People using "deterministic: true" will get unique indexes working out
of the box.
- The system will encourage keeping deterministic encryption stable:
- By always using oldest encryption schemes
- By forbidding configuring multiple keys
But you can still opt-out of the default if you need to.