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!
Sha1EnvelopeEncryptionKeyProvider
and restart GDK
5. Update the model to use # 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-----
# ...