Rails 5.1 introduced encrypted secrets, which gives you two places to put your secrets — secrets.
Rails 5.2 replaces both secrets with encrypted credentials. You cannot use plain text credentials.
Encrypted Credentials
To use encrypted credentials, you need a key. Without this encryption key, you won’t be able to decrypt your credentials. It’s safe to commit the encrypted file to your repository but you should never commit the encryption key.
The key, located config/master.key
rails new
.gitignore
The encrypted credentials are saved config/credentials.yml.enc
bin/rails credentials:edit
Your text editor will open an unencrypted version of your credentials. If you don’t have EDITOR set, you can EDITOR=vi bin/rails credentials:edit
After saving the file, the encrypted version will be saved config/credentials.yml.enc
Reading the Credentials
If you want to use the credentials in the production environment, add the following to config/environments/production.rb
config.require_master_key = true
You can access the credentials with Rails.application.credentials. For example, if you
foo: bar
Rails.application.credentials.foo
Credentials Format
You can use any valid YAML on your credentials. Rails development
production
aws:
access_key_id: 123
secret_access_key: 345
You can access these credentials with Rails.application.credentials.aws[:access_key_id]
and Rails.application.credentials.aws[:secret_access_key]
There’s nothing stopping you from production
production:
aws:
access_key_id: 123
secret_access_key: 345
You can access the credentials Rails.application.credentials.production[:aws][:access_key_id]
Rails.application.credentials.production[:aws][:secret_access_key]
Advantages of Encrypted Credentials
-
First the obvious: your credentials are encrypted. No one will be able to decrypt your credentials without the key.
-
The encrypted credentials are saved in your repository. You’ll have a history of the changes and who made them.
-
You deploy new credentials together with your code. If you add code to access an API for example, you can deploy that code together with the token on credentials.yml.enc. Previously, you’ll have to make sure you add the environment variable before deploying the new code.
-
All secrets are in one location. Instead of managing multiple environment variables, everything is in one file.
Managing the Key
While using encrypted credentials provides a number of advantages over unencrypted secrets, we still have to find a way to put the key in place. Our options are similar to handling secrets pre-Rails 5.1. You cannot save the key to your repository because someone who can access your code can then decrypt the credentials.
-
Upload master.key securely.
You can
scp orsftp the file. In Engine Yard, you only have to do this once. When you scale your environment, the new servers will get a copy of master.key.Upload the key to a shared directory. Shared here means shared between releases, not a shared filesystem. On each deploy, you symlink config/master.key to /path/to/shared/config/master.key. You can do this on a deploy hook on Engine Yard or in Capistrano.
If you need to give a developer a copy of the key, never send it via email (unless you’re using encrypted emails which most of us don’t!) You can use a password manager because they use encryption.
-
Put the key on the RAILS_MASTER_KEY environment variable.
In some cases where you can’t upload a file, this is the only option. Even though this is convenient, make sure you know the risks of using environment variables. The risks can be mitigated, but if you can upload master.key then use that option.
A Note on Secret Key Base
The key used to encrypt credentials is different from the secret key base. The key on master.key is used to encrypt and decrypt all credentials. It does not replace the secret key base.
The secret key base is required by Rails. If you want to generate a new secret key base run,
bin/rails secret
and add that to your credentials by bin/rails credentials:edit
Conclusion
Encrypted credentials offer a few advantages over plaintext credentials or environment variables. Rails like many times in the past