Skip to content

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-----
# ...
Edited by Avielle Wolfe

Merge request reports

Loading