I made a step-up update from Rails 7.1.5.1 to 7.2.2.1 (on my way to Rails 8). Didn’t touch any Message Encryptor/Verifier related settings, not that I’d set any in the first place. Didn’t change any creds, nothing. Now my encrypted cookie (still sitting in the browser from the previous version of Rails) can no longer be read, shows up as nil.
As soon as I stash the update in git stash, Rails starts understanding the cookie again.
Why can’t the new Rails version read this cookie? I don’t see any mention of this in the upgrade guide. Can’t just sign out everybody.
Just discovered that Rails.application.secret_key_base is not the same before and after upgrade. In 7.1 in reads it from credentials. In 7.2 I have no idea what it’s doing. Just deleted tmp/local_secret.txt but it keeps creating a new one there every time I check Rails.application.secret_key_base. It won’t look in credentials anymore.
Yeah, basically this code seems incorrect. It always generates a new secret, and never honors the secret stored in credentials when in a local environment. Am I missing something?
If I set it manually like this in my development.rb, then it works:
Previous to 7.1 the tmp/local_secret.txt file took precedence just as it does in 7.2. It would appear that the bug was in 7.1 causing your app to use the encrypted secret rather than the tmp file.
The fix for you would have been to copy the key from your encrypted secrets and put it in tmp/local_secret.txt being sure not to append a line break to the end of the file.
The fix I implemented while waiting for the PR was to explicitly set config.secret_key_base in development.rb file to the one stored in credentials. This is way more convenient than having to tell all developmers to create tmp/local_secret.txt file on their machines.
I’m curious what’s the rationale for looking at local_secret.txt first? Wouldn’t reading it from credentials first be more consistent with other environments? I’m probably missing some kind of valid case where this messes things up, but can’t think of any.
Back when this was introduced in Rails 5.something the idea was that there would just be one encrypted credentials file, generally used for production. Of course there was the glaring edge case that you probably didn’t want to use or share the secret key from production in your development environment so they came up with the development_secret.txt (later renamed) in order to override the production key. I wish I could find the comments on GitHub, but people were challenging the decision do not have credentials partitioned by environment as they were before this change but the reply was essentially “this is the way it is now”. Someone must have seen the light in the end and added environment specific credentials but for those of us on the long upgrade path, this just adds complication.