Using Rails 4.1 Secrets for Configuration
I previously wrote about how I handle environment configuration in Rails. Along with solutions like the dotenv gem, it relies on entirely on environment variables.
One of the highlighted features of Rails 4.1 was the config/secrets.yml
file. By default, this file contains the secret_key_base
and defers to the ENV variable of the same name in the production environment. Even though secret_key_base
isn’t typically referenced explicitly in an application, I was curious if I could use the config/secrets.yml
file in place of previously documented configuration solution.
After a little digging, it turns out that it works perfectly. A valid question is whether the variables are better referenced through the Rails.application
hash, but that’s probably more a preference and use-case dependent decision. Either way, we’ll explore the solution below.
The Question
Below is a default config/secrets.yml
file generated from a Rails 4.1 app. As you can see, both the development and test environments rely on statically set values, where the production environment relies on environment variables being set on the system. The latter is perfect for platforms like Heroku, and just as easy if you manage your own systems on EC2 or similar infrastructure.
Notice how ERB is processed in the file. This gives us the opportunity to use Ruby to generate random strings, dates, or anything else that can be expressed through code.
So can we use it for other configuration values in the application?
The Solution
In order to figure out where the output of the parsed secrets file was stored, I pulled the latest Rails changes and went code diving.
The first thing I did was search “secrets”. The first group of results were mostly comments related to the processing of secret_key_base
and where it could be found. After combing through a few more results, I came across the Rails::Application
class.
A static array at the top of the file seemed to hold some values for the application as shown below:
Looks like we’re on the right track. Going further down the file leads us to the getter:
As you can see, the file path config/secrets
is referenced as the yaml
source:
and the result of reading the file is sent through ERB and YAML:
The environment group is parsed:
The result of the output is returned, leaving us with a hash of options based on the environment group. With a little luck we should be able to query the application from the console and get the configuration values.
That’s great news because it means we can put other values in this file and reference them throughout our application using the parent hash Rails.application.secrets
.
For example, let’s assume we need to configuration Pusher URL again. We could add it to the secrets.yml
file like so:
Now within our application we can set the Pusher URL within the initializer using the secret value:
Summary
I feel like my previous solution has the potential to be replaced with the secrets file. I plan to try it out in an upcoming application and see if it’s as easy to manage as it seems.
Note that by default, the secrets.yml
file is NOT ignored by git. If you plan to include passwords or other sensitive data in the file, be sure to add it to your .gitignore
.