Decrypt Lockbox files with every db_key_base key
What does this MR do and why?
Files encrypted with Lockbox can now be decrypted with any configured db_key_base key. This is Phase 1.2 of making the db_key_base secret rotatable.
db_key_base can be an array: the last key encrypts, every key decrypts. Terraform::StateUploader and Ci::PipelineArtifactUploader derived their per-project file key with HMAC-SHA256 over the raw credential. With a list of keys that value is an Array, and OpenSSL::HMAC.digest raises. After a key swap, files written with the old key must also still decrypt.
The new Gitlab::Encryption::DbKeyBaseLockboxKeys module derives the file key from the current key through Gitlab::Encryption::KeyProvider[:db_key_base]. It passes older keys to Lockbox as previous_versions, newest first, and skips copies of the current key. Both uploaders now call encrypt(key: ..., previous_versions: ...).
Nothing changes for instances today. config/settings.rb still raises when more than one key is configured (removed in Phase 3). With a single key, the derived file key is byte-identical and there are no previous versions.
Why previous_versions
Lockbox tries the current key first, then each previous version. It uses AES-GCM, so a wrong key fails cleanly and the next one is tried. Re-encrypting existing files with the new key is Phase 5: https://gitlab.com/gitlab-org/gitlab/-/work_items/631459
Specs cover the new module (single key, several keys newest first, duplicated keys) and each uploader: a file written with the old key still reads after switching to [old, new], and a new file is written with the current key and reads with [new] only. Removing previous_versions makes exactly the two "previous key" examples fail. The new helper stub_db_key_base_keys(*keys) stubs the keys.
References
- Issue (Phase 1.2): https://gitlab.com/gitlab-org/gitlab/-/work_items/631579
- Epic: https://gitlab.com/groups/gitlab-org/-/work_items/23829
- Phase 1 MR: !258705 (merged)
- Phase 3: https://gitlab.com/gitlab-org/gitlab/-/work_items/631456
Screenshots or screen recordings
Not applicable, backend only.
How to set up and validate locally
- Run
bin/rspec spec/lib/gitlab/encryption/db_key_base_lockbox_keys_spec.rb spec/uploaders/terraform/state_uploader_spec.rb spec/uploaders/ci/pipeline_artifact_uploader_spec.rb
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.