The Marriage of Figaro… and Rails
Two years ago and 264,309 downloads ago, I wrote the Figaro gem. I had been using the pattern for some time already and was frustrated that something so simple wasn’t already included in Rails. And now, finally, it is! Well… sort of.
For those of you who are unfamiliar, Figaro loads the contents of
application.yml and merges the values into
ENV. The purpose is to provide Git-ignored configuration for sensitive information like API keys and other secrets.
# config/application.yml stripe_publishable_key: pk_test_TLr0qqdKhm0yX1bZtKC4kFAC stripe_secret_key: sk_test_Qbppb2nkFEzPoquOdBym0JL2 # config/initializers/stripe.rb Stripe.api_key = ENV["stripe_secret_key"]
The purpose of the new
secrets.yml file is the same: to keep sensitive configuration information out of source control. Plus, the implementation is similar.
# config/secrets.yml stripe_publishable_key: pk_test_TLr0qqdKhm0yX1bZtKC4kFAC stripe_secret_key: sk_test_Qbppb2nkFEzPoquOdBym0JL2 # config/initializers/stripe.rb Stripe.api_key = Rails.application.secrets.stripe_secret_key
On the surface, this Rails feature looks like a Figaro-killer! Figaro even received a new GitHub issue within hours of the Rails release:
This is definitely a step in the right direction but it makes me sad for Figaro :(
However, there are some notable differences between the two approaches. Rails’
secrets.yml has pros and cons when compared to Figaro’s
- Convention. Now that there’s an agreed upon convention in the Rails community, there can be a familiarity amongst developers as to how to properly configure a Rails application. Plus, services like Heroku and Travis have the opportunity to support the new convention.
- Rich object support.
ENVis limited to string key-value pairs. Oftentimes, an application needs configuration for a number of days or a fee percentage. These numeric values must be cast to strings when written and re-cast when read.
- Secure defaults. Now that Rails has a way to store sensitive information, newly generated applications will not check the
secret_key_baseinto source control. Knowledge of the
secret_key_baseallows an attacker to read and manipulate an application’s cookies, exposing your application to remote code execution. Revealing the
secret_key_basevalue can be absolutely devastating.
- The Twelve-Factor App. The twelve-factor methodology outlines best practices for application development in twelve areas, and arises from the experience of prominent application developers and maintainers working on the Heroku platform. One of the twelve areas is Config. It’s a great read! tl;dr: Use
- Deployment. Because
ENV, configuring your production application requires installing
secrets.ymlremotely for every application server. This doesn’t play well with Heroku’s existing configuration conventions using, you guessed it…
I don’t believe that Rails 4.1’s
secrets.yml is a perfect solution for application configuration, but it is a fantastic start!
When I started to write Figaro two years ago, it was as a pull request to Rails. So don’t be sad for Figaro! I’m very happy to see that a variation on Figaro finally made its way into Rails.
That said, there may still be a place for Figaro and I’d love to hear your thoughts here on what Figaro’s future might look like.
Add another con to the list. As of now, Rails does not Git-ignore
secrets.yml by default. Going through the motions of generating a new Rails application will still commit the sensitive
secret_key_base value to source control. I expect that this will be resolved before Rails 4.1.0 is released.