Enable SHA256 encryption for ActiveRecord
What does this MR do and why?
This MR reenables SHA256 encryption. The previous attempt to enable the encryption resulted in an incident because the support_sha1_for_non_deterministic_encryption setting does not apply to envelope encryption. Rolling back the change resolved most of the errors, but pipeline schedule inputs records created using SHA256 broke after the rollback.
This MR solves both problems. It implements Sha1EnvelopeEncryptionKeyProvider and uses it as a fallback for envelope encryption, and it reenables SHA256 encryption (which fixes the broken inputs records).
Issue: "There was a problem fetching pipeline schedule... (#572297 - closed)
Changelog: fixed
References
Incident: https://gitlab.com/gitlab-com/request-for-help/-/issues/3467
Original enabling: Add Rails 7.1 as default configuration (!203744 - merged)
Revert of original enabling: Revert "Merge branch 'bmarjanovic/set-default-7... (!204327 - merged)
How to set up and validate locally
1. Begin in a pre-Rails 7.1 state and start GDK
# config/application.rb
config.active_record.encryption.hash_digest_class = OpenSSL::Digest::SHA1
# config.active_record.encryption.support_sha1_for_non_deterministic_encryption should not be present
# ee/app/models/cloud_connector/keys.rb
module CloudConnector
class Keys
# ...
encrypt :secret_key, key_provider: ActiveRecord::Encryption::EnvelopeEncryptionKeyProvider.new
# ...
end
end
Start GDK
2. Create a cloud connector key with SHA1 encryption
# RAILS CONSOLE
rsa_key = OpenSSL::PKey::RSA.new(2048)
CloudConnector::Keys.create!(secret_key: rsa_key.to_pem)
3. Update the encryption settings and restart GDK
# config/application.rb
config.active_record.encryption.hash_digest_class = OpenSSL::Digest::SHA256
config.active_record.encryption.support_sha1_for_non_deterministic_encryption = true
Restart GDK
4. In the Rails console, see that you get a Decryption error
# RAILS CONSOLE
key = CloudConnector::Keys.last
key.secret_key # ActiveRecord::Encryption::Errors::Decryption!
5. Update the model to use Sha1EnvelopeEncryptionKeyProvider and restart GDK
# ee/app/models/cloud_connector/keys.rb
module CloudConnector
class Keys
# ...
encrypt :secret_key, previous: { key_provider: Gitlab::Encryption::Sha1EnvelopeEncryptionKeyProvider.new }
# ...
end
end
Restart GDK
6. See that the SHA1 key can now be decrypted 🎉
# RAILS CONSOLE
key = CloudConnector::Keys.last
key.secret_key
# No error!
# -----BEGIN RSA PRIVATE KEY-----
# ...