Rails Secrets

Something new to Rails 4.1 is the secrets.yml file. It took a bit of debate to figure out how the Heathify team would implement this new rails convention, but we finally achieved what we deemed a workable solution.

If you don't know what I'm talking about, it's a new rails config file for storing your secret_key_base, among other values you'd prefer not to check into your repository. This could be any API keys or perhaps an email account you use for playing with email in development. Up until now, Healthify has maintained these as environment variables in a .env file and we just rewrite the environment variables all throughout the application. Unforunately, this was messy to work with across developer environments without our environment variables stored in one place. We ultimately decided to use the secrets.yml file as a mapping from our environment variables in our .gitignored .env file to our use of those values throughout the application.

Something like our email config would go from this:

#config/environments/development.rb OLD
config.action_mailer.smtp_settings = {  
  address: "smtp.gmail.com",
  port: 587,
  domain: "gmail.com",
  authentication: "plain",
  enable_starttls_auto: true,
  user_name: ENV['EMAIL'],
  password: ENV['EMAIL_PASSWORD']
}

To this:

#config/environments/development.rb NEW
config.action_mailer.smtp_settings = {  
  address: "smtp.gmail.com",
  port: 587,
  domain: "gmail.com",
  authentication: "plain",
  enable_starttls_auto: true,
  user_name: Rails.application.secrets.smtp_username,
  password: Rails.application.secrets.smtp_password
}
#config/secrets.yml NEW
development:  
  secret_token: "xxxxxxxxxxxxxxxxxxxxxxx"
  smtp_username: <%= ENV['EMAIL'] %>
  smtp_password: <%= ENV['EMAIL_PASSWORD'] %>

This does come across as redundant to a certain degree but a large factor in our decision to do this was an effort to mimic our production environment and the environment variables there, which aren't checked into our repo.

The conclusion is, every environment has it's own secret list of environment variables - whether it's staging, production, or each developer. Then we match those secret values with the identical mapping across every developer's environment. Lastly, those mappings then allow for uniform variable usage throughout the app. Maintenance is easy because all of the variables are declared in one file.