Rails 5.2 credentials
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 config/secrets.yml
and config/secrets.yml.enc
.
The intention behind this change is mainly to remove some of the confusion introduced by the combinations of config/secrets.yml
, config/secrets.yml.enc
and 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:
config/credentials.yml.enc
config/master.key
Using new Rails credentials
When you upgrade Rails to v5.2, the file where you are going to store all your private credentials is config/credentials.yml.enc
.
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.
The 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.
Editing Credentials
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/master.key
and config/credentials.yml.enc
don’t exist, Rails will take care of creating them on your behalf.
Reading credentials
Let’s assume that the unencrypted version of your config/credentials.yml.enc
file looks like this:
aws:
access_key_id: 123
secret_access_key: 345
secret_key_base: 2fdea1259c6660852864f9726616df64c8cd
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 config/credentials.yml.enc
.
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:
development:
aws:
access_key_id: 123
secret_access_key: 345
secret_key_base: 2fdea1259c6660852864f9726616df64c8cdproduction:
aws:
access_key_id: 321
secret_access_key: 543
secret_key_base: hu23ih41iu23h4123u4h23iu4h2323j412i3
Then, simply add the environment namespace when you access the configs:
Rails.application.credentials[Rails.env.to_sym][:aws][:access_key_id]
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.key
file in the server. You’ll normally want to symlink this file to a shared folder in the server filesystem. Again, do not version yourconfig/master.key
file. - Option 2: create a
RAILS_MASTER_KEY
ENV 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
and 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/environments/production.rb
file:
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 config/master.key
.
Conclusion
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.
If you want to read more about this, you can take a look at DHH’s Pull Request for the initial description and implementation of the change.