Rails 7.1 - migrate from secrets.yml to credentials.enc.yml [Short]

24th October 2023 – 290 words

If you have been using the Rails.application.secrets feature, you have been able to ignore the deprecation until Rails 7.1. But now, Secrets is gone! We had been using config/secrets.yml in the past because our deployment script would just replace the file during deployment.

The “new” credentials on the other hand want to be kept in your repository, encrypted. We used the following playbook to migrate our secrets to the new format:

Development / Test

Use the Rails commands to generate the credentials and a random key. During the generation, it will pop open your editor and you can copy over the secrets from the old secrets.yml and respective environment onto the top level:

rails credentials:edit --environment development
rails credentials:edit --environment test

Then, in our case, the dev/test credentials are all fake anyway, so we will commit the keys to the repository:

# Copy over stuff from secrets,
# might commit dev/test key:
git add config/credentials/test.key -f
git add config/credentials/development.key -f

production

Generate the key and credentials file the same way:

rails credentials:edit --environment production
# use content of config/credentials/production.key and set it as Environment Variable RAILS_MASTER_KEY in ansible
cat config/credentials/production.key

Put the content of the production.key somewhere in your production pipeline as the environment variable RAILS_MASTER_KEY= (e.g. Heroku env, Ansible env, Docker env, etc.)

Migrate usage

Lastly, replace usages of Rails.application.secrets with Rails.application.credentials, here using the awesome sd + rg tool instead of sed. Our use find&replace all in your editor of choice:

sd application.secrets application.credentials `rg application.secrets -l`