Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove memoization to accept key_provider overridden by with_encryption_context #51019

Merged
merged 1 commit into from
Feb 13, 2024

Conversation

jhawthorn
Copy link
Member

Somewhat similar to #48923 (but with a different cause), as of 7.1 we weren't correctly observing key_provider when overridden with with_encryption_context. I believe this regressed in #44540 (though it feels possible in some cases there would have been a memoization problem beforehand).

Reported by @kstevens715. Thank you!

I'll also backport this to 7-1-stable

This is necessary to allow key_provider to be changed dynamically using
with_encryption_context.

Co-authored-by: Kyle Stevens <kstevens715@gmail.com>
Copy link
Contributor

@jorgemanrubia jorgemanrubia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @jhawthorn!

@jhawthorn jhawthorn merged commit c730877 into rails:main Feb 13, 2024
4 checks passed
jhawthorn added a commit that referenced this pull request Feb 13, 2024
Remove memoization to accept `key_provider` overridden by `with_encryption_context`
@jhawthorn jhawthorn deleted the key-provider branch February 13, 2024 21:53
@jhawthorn
Copy link
Member Author

Backported to 7-1-stable as ad032f4

rosa added a commit to rosa/rails that referenced this pull request Mar 13, 2024
The memoization of Scheme#key_provider was removed completely in
rails#51019 because it prevented
overriding the `key_provider` via `with_encryption_context`. However,
this also made our tests for the HEY app about 5 times slower. We traced
this down to all attributes where we either provide a key or declare them
as deterministic and have to derive a key to instantiate the provider
every time we load them. This might happen hundreds of times per test,
and ultimately, we call
```
ActiveSupport::KeyGenerator#generate_key
```
and
```
OpenSSL::KDF.pbkdf2_hmac
```
hundreds of times. This adds significant overhead per test.

In reality, what's overridden bv `with_encryption_context` is the value
used as default provider, that is, `ActiveRecord::Encryption.key_provider`.
This is only used in `Scheme#key_provider` if the scheme doesn't already have
either a `key_provider` passed directly, or a `key`, or is `deterministic`.
The `key_provider` passed directly is already memoized simply by having it
stored as is. Let's memoize the other two, in order, so we save all those
extra calls to derive the same keys again and again.
rosa added a commit to rosa/rails that referenced this pull request Mar 13, 2024
The memoization of Scheme#key_provider was removed completely in
rails#51019 because it prevented
overriding the `key_provider` via `with_encryption_context`. However,
this also made our tests for the HEY app about 5 times slower. We traced
this down to all attributes where we either provide a key or declare them
as deterministic and have to derive a key to instantiate the provider
every time we load them. This might happen hundreds of times per test,
and ultimately, we call
```
ActiveSupport::KeyGenerator#generate_key
```
and
```
OpenSSL::KDF.pbkdf2_hmac
```
hundreds of times. This adds significant overhead per test.

In reality, what's overridden bv `with_encryption_context` is the value
used as default provider, that is, `ActiveRecord::Encryption.key_provider`.
This is only used in `Scheme#key_provider` if the scheme doesn't already have
either a `key_provider` passed directly, or a `key`, or is `deterministic`.
The `key_provider` passed directly is already memoized simply by having it
stored as is. Let's memoize the other two, in order, so we save all those
extra calls to derive the same keys again and again.
viralpraxis pushed a commit to viralpraxis/rails that referenced this pull request Mar 24, 2024
The memoization of Scheme#key_provider was removed completely in
rails#51019 because it prevented
overriding the `key_provider` via `with_encryption_context`. However,
this also made our tests for the HEY app about 5 times slower. We traced
this down to all attributes where we either provide a key or declare them
as deterministic and have to derive a key to instantiate the provider
every time we load them. This might happen hundreds of times per test,
and ultimately, we call
```
ActiveSupport::KeyGenerator#generate_key
```
and
```
OpenSSL::KDF.pbkdf2_hmac
```
hundreds of times. This adds significant overhead per test.

In reality, what's overridden bv `with_encryption_context` is the value
used as default provider, that is, `ActiveRecord::Encryption.key_provider`.
This is only used in `Scheme#key_provider` if the scheme doesn't already have
either a `key_provider` passed directly, or a `key`, or is `deterministic`.
The `key_provider` passed directly is already memoized simply by having it
stored as is. Let's memoize the other two, in order, so we save all those
extra calls to derive the same keys again and again.
fractaledmind pushed a commit to fractaledmind/rails that referenced this pull request May 13, 2024
The memoization of Scheme#key_provider was removed completely in
rails#51019 because it prevented
overriding the `key_provider` via `with_encryption_context`. However,
this also made our tests for the HEY app about 5 times slower. We traced
this down to all attributes where we either provide a key or declare them
as deterministic and have to derive a key to instantiate the provider
every time we load them. This might happen hundreds of times per test,
and ultimately, we call
```
ActiveSupport::KeyGenerator#generate_key
```
and
```
OpenSSL::KDF.pbkdf2_hmac
```
hundreds of times. This adds significant overhead per test.

In reality, what's overridden bv `with_encryption_context` is the value
used as default provider, that is, `ActiveRecord::Encryption.key_provider`.
This is only used in `Scheme#key_provider` if the scheme doesn't already have
either a `key_provider` passed directly, or a `key`, or is `deterministic`.
The `key_provider` passed directly is already memoized simply by having it
stored as is. Let's memoize the other two, in order, so we save all those
extra calls to derive the same keys again and again.
xjunior pushed a commit to xjunior/rails that referenced this pull request Jun 9, 2024
The memoization of Scheme#key_provider was removed completely in
rails#51019 because it prevented
overriding the `key_provider` via `with_encryption_context`. However,
this also made our tests for the HEY app about 5 times slower. We traced
this down to all attributes where we either provide a key or declare them
as deterministic and have to derive a key to instantiate the provider
every time we load them. This might happen hundreds of times per test,
and ultimately, we call
```
ActiveSupport::KeyGenerator#generate_key
```
and
```
OpenSSL::KDF.pbkdf2_hmac
```
hundreds of times. This adds significant overhead per test.

In reality, what's overridden bv `with_encryption_context` is the value
used as default provider, that is, `ActiveRecord::Encryption.key_provider`.
This is only used in `Scheme#key_provider` if the scheme doesn't already have
either a `key_provider` passed directly, or a `key`, or is `deterministic`.
The `key_provider` passed directly is already memoized simply by having it
stored as is. Let's memoize the other two, in order, so we save all those
extra calls to derive the same keys again and again.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants