As announced in Rails 5.2.0 release candidate, Rails 5.2 will go out with a brand new
credentials API that will eventually replace the current
The intention behind this change is mainly to remove some of the confusion introduced by the combinations of
SECRET_BASE_KEY used in earlier versions of Rails, and attempt to unify everything using a more straightforward approach.
From now on, Rails 5.2 will only intend to use these two files instead:
Using new Rails credentials
When you upgrade Rails to v5.2, the file where you are going to store all your private credentials is
As it’s extension suggests, this file is going to be encrypted - so you won’t be able to read what’s inside of it - unless you have the proper master key to decrypt it. This is why it IS safe to version this file into your source control tool.
The second file,
config/master.key, is the file where your
RAILS_MASTER_KEY will be placed.
RAILS_MASTER_KEY is the key that Rails will use to decrypt your
config/credentials.yml.enc. It is NOT a good idea to version
config/master.key file into your source control tool. You need to keep it as a secret, so make sure to list it in your .gitignore file if you’re using git.
Since it’s encrypted, Rails 5.2 comes with a way to edit the
config/credentials.yml.enc file. You can do that by running the following command:
EDITOR=vim rails credentials:edit
This will open up a vim editor with the decrypted version of the file (you can use others editors too, not necessarily vim). When you save it, it will encrypt it again using your master key.
You’ll see that the decrypted version of the file looks like any other normal .yml file.
By the time you run the
credentials:edit command, If
config/credentials.yml.enc don’t exist, Rails will take care of creating them on your behalf.
Let’s assume that the unencrypted version of your
config/credentials.yml.enc file looks like this:
Then, you should be able to access the configuration programmatically like this:
Rails.application.credentials.aws[:access_key_id] # => "123"
Rails.application.credentials.aws[:secret_access_key] # => "345"
Rails.application.credentials.secret_key_base # => "2fdea...
Credentials & Environments
The Rails team is proposing to remove the environment scopes inside
This new file is a flat format, not divided by environments, like secrets.yml has been. Most of the time, these credentials are only relevant in production, and if someone does need to have some keys duplicated for different environments, it can be done by hand. [DHH]
Nevertheless, you can always edit
config/credentials.yml.enc and add namespaces for your secrets under development, test or production like the ones you would have in the old
config/secrets.yml. You can structure your
config/credentials.yml.enc like this:
Then, simply add the environment namespace when you access the configs:
Deploying master key
When you move your code to a server, you need to make sure that your
config/credentials.yml.enc file can be decrypted. That means that somehow you’ll need to provide Rails with your master key, given that it is not checked into version control.
There are two ways of doing that:
- Option 1: Place the
config/master.keyfile in the server. You’ll normally want to symlink this file to a shared folder in the server filesystem. Again, do not version your
- Option 2: create a
RAILS_MASTER_KEYENV variable. Rails will detect it and use it as your master key, e.g. in heroku:
heroku config:set RAILS_MASTER_KEY=<your-master-key-here>.
You should be able to use any of those indistinctly.
Upgrading from previous Rails
Keep in mind that the
config/secrets.yml.enc will continue to work and will still be compatible with Rails 5.2
Note: We will just keep Rails.secrets and friends around. The Rails.application.credentials setup will be a new, concurrent approach. All new apps would use it, but we wouldn’t need to screw existing apps. [DHH]
That won’t be forever though, so it’s not a bad idea to think about upgrading soon.
If you are upgrading your app, and not starting from a brand new Rails 5.2 app, make sure to add the following configuration to your
config.require_master_key = true
This will tell Rails to ensure that a master key has been made available from either
ENV['RAILS_MASTER_KEY'] or in
In general, I understand what the motivation behind this change is and I support it. If the old approach was confusing for a lot of people I believe it’s a good thing that the Rails team tries to improve it. Hopefully people will adopt it and it will become the standard for everyone.