Allow several db_key_base keys

What does this MR do and why?

  • db_key_base can now be a list. The last key is the current one (it encrypts and signs). Every key decrypts. This is the same convention as the Active Record Encryption keys.
  • Settings.db_key_base_keys no longer raises MultipleDbKeyBaseError when more than one key is configured. The constant is removed.
  • When db_key_base is missing (new source installs, GDK, CI test env), the generated default is now an array with one key. A new key can later be appended to rotate. Existing string values keep working.
  • With a single key, behaviour is unchanged.
  • This alone does not make rotation operational. Re-encryption and the runbook come in later phases.

Merge this last: it depends on the MRs listed under References.

References

Screenshots or screen recordings

Not applicable: no UI change.

How to set up and validate locally

  1. Back up config/secrets.yml. In its development section, set db_key_base to a list: a new key, then your current one ([<new>, <current>]). The current key stays last, so it keeps encrypting.
  2. Start a new Rails console. Check that Settings.db_key_base_keys returns both keys, and that Gitlab::Encryption::KeyProvider[:db_key_base].encryption_key.secret is your current key.
  3. Remove db_key_base from config/secrets.yml and start a console again. The regenerated value in config/secrets.yml is a one-element list.
  4. Restore your backup of config/secrets.yml.

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.

🤖 Generated with Claude Code

Merge request reports

Loading
Loading