How to rotate secrek_key_base without breaking ActiveStorage/ActionText attachments?

This unmerged PR makes the point that ActiveStorage URLs will break if the app’s secret_key_base gets changed (also see issues #40352, #40614). It suggests registering a rotator to update the old URLs. Is the below initializer the recommended way?

# config/initializers/rotators.rb

Rails.application.config.after_initialize do |app|
  old_secret_key_base = Rails.application.credentials.dig(:old_secret_key_base)
  ActiveStorage.verifier.rotate(old_secret_key_base, digest: "SHA256", serializer: Marshal)
end

How does one then identify and actually update the URLs so that they use the new secret? How to figure out when the rotator can be safely removed? I suppose having a new secret key base is not much use as long as there are rotators still registered, as it means the old secret key base can still be used. An unmerged PR suggests to add instrumentation to monitor when a rotator using an old key is actually called (any suggestion to what kind of monitoring tool to send these notifications?). I suppose the idea is to plot these notifications in time and once they flatline e.g a few weeks, then the rotator could be removed.

How will this fix the signed IDs which are embedded straight in Action Text rich text (stored in DB in action_text_rich_texts body column)? Is adding the above initializer enough to keep old ActionText embeds working? How to then mass-update all the signed IDs stored in the rich text in DB? Is it necessary to somehow manually edit and save each rich text record for the new secret key base to start being used?

It’s also unclear to what extent all this discussion about changing the secret_key_base applies when changing other things involved in encryption like the digest class and serializer. For instance, are the ActiveStorage/ActionText URLs and embeds impacted by the recent change of digest class to SHA256 in Rails 7?

Would anyone have experience to share on the topic? Shouldn’t this be documented somewhere to make sure others don’t fall in a similar trap when trying to rotate their secret_key_base or other things (which already happened)?

2 Likes