An intro to Encrypted Secrets in Ruby on Rails
Rails 5.1 introduced Encrypted Secrets to help simplify the management of your application secrets (things such as service credentials and the secret_key_base). This article details the feature and its usage.
Why Encrypted Secrets?
Since Rails 4.1, the framework has given you the ability to centrally store secrets in the
config/secrets.yml file. The glaring shortcoming of secrets.yml is that the file actually is in no way secure, and you cannot actually safely check it into version control with any production credentials. The convention for production credentials was always to load them within
secrets.yml but from the host environment. Usually your secrets file would end up looking something like this:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
some_api_key: <%= ENV["SOME_API_KEY"] %>
Rails 5.1+’s Encrypted Secrets feature means you can now keep production secrets in a second fully encrypted file (AES-256 by default), which is managed by the framework. Secrets from the encrypted
secrets.yml.enc file are merged with secrets from the unencrypted
Getting started with Encrypted Secrets
Encrypted secrets is not set up by default, and in order to bootstrap it you need to run:
This will drop a few files into your project tree:
- config/secrets.yml.key – contains the actual secret key used by the framework to AES-encrypt your secrets.
- config/secrets.yml.enc – the encrypted digest form of your (encrypted) secrets.
It should go without saying that the
config/secrets.yml.key file should be handled carefully and never checked into version control as it is all that is required to decrypt your secrets (it is accordingly gitignored by default).
To edit your secrets, invoke the command:
If you have no EDITOR variable defined in your shell environment you will need to set one. For Sublime Text, you can add the following to your
.bash_profile (or similar shell configuration file).
# Export a default text editor.
# Assumes you have set up "subl":
export EDITOR="subl -w"
secrets:edit task will decrypt your secrets and pop them open in your editor where you can make changes. When you quit the editor, the framework will re-encrypt the secrets and overwrite the existing
Usage in production
In production, Rails will look for the decryption key either in the environment variable
RAILS_MASTER_KEY or in a local copy of the key file (
config/secrets.yml.key). How you get the environment variable exposed to your application or how you inject the key file is a matter that is specific to your particular hosting and infrastructure management setup.
It is important to understand that using Encrypted Secrets over other solutions does have drawbacks. It is likely to fit best within projects that have small and very trusted teams. Because every developer who is expected to manage secrets in an application must have a local copy of the encryption key, situations like terminating an employee become somewhat complicated. More specifically you would need an efficient solution to quickly rotate your encryption key in production, and also to quickly distribute a new key to all developers.
For this reason you may want to consider another solution if your organization is of a certain scale. What the best such solution is will likely come down to details of your infrastructure management and hosting, but no matter what it will likely be a matter of having credentials exposed via the ENV. PaaS solutions like Heroku, CloudFoundry and Cloud66 all provide ENV variable management faculties, and such solutions are better equipped to handle the practical security needs of larger organizations.