Secret Keeping with Rails
Ever needed to store some secrets in Rails that you don’t want to share with the world? Yeah, same! In this post, I’m going to outline a really simple way to store your application’s secrets in a file called
Rails configuration and you
First of all, let’s discuss exactly how this is going to work. If you’ve even configured a Rails app before, you may have noticed that you’re setting your configuration on a
config object inside a block that looks a bit like this:
Something you might not know, though,is that these configuration settings are then available on an object called
Rails.configuration. What we’re going to do is add an initializer that loads a secrets file, and then loads them into the
Rails.configuration object so that we can access them in our application.
The advantage of this method versus something like Foreman is that:
- This method is much closer to Rails conventions - for example, instead of using a dotfile, it uses a basic initializer
- It doesn’t require running your application through any special interface like Foreman does
- It just does one thing, and does it well - storing configuration.
Reading the config file
As I’ve mentioned, we’ll be reading a file called
config/secrets.yml. Let’s get our application set up to load this file.
NB: For this example, I’m assuming you’ve got a Rails 3.x application set up - you don’t need any models, controllers or anything else - we can test this from a
First of all, add the configuration file:
- as you can see, this secrets file just contains some credentials to use with Facebook OAuth - it can contain as many keys as you like, however.
Next we need to add a gem to our
Gemfile. This gem is called
Hashie, and extends Ruby’s
Hash object to do some cool stuff - in our case, we can pass it a hash, and it will give us method access to our secrets - in other words, we can do this:
As a bonus, if you’re using Omniauth and any Omniauth strategies, you’ve probably already installed
Hashie as a dependency of one of these - we’re just doing to re-use it here, so let’s add it to our Gemfile and be specific:
Next, let’s add an initializer to load this file in
config/initializers/01_load_secrets. The “01” part is important; it tells Rails to load it before any other initializer runs (since we might need our secrets straight away in an initializer):
I’ll just talk through what this is doing:
- First, we open a configuration block for our application - this gives us access to a
configobject we can set keys on
- Next, we load the YAML file we created, but only pull in keys for the Rails environment we are running in - this let’s us have keys for
development, etc. in a single file.
- Finally, we wrap that YAML file load in a
Hashie::Mash. Hashie is just a collection of Hash extensions that, in this case, gives turns our Hash (which is what
YAML.load_filereturns) into an object with method access (so we can go
That’s all we need to do to load the config in - as you can see, it’s actually a really simple operation, and use of Hashie means that we don’t need to mess up our code later down the track with lots of square brackets and hash keys.
Once we’ve got the file loaded, actually using the configuration is actually really easy - just access your top-secret secrets on
For reference, here’s how you might set [Omniauth] to support logging in with Facebook using our new