Safeguarding Your API Keys
I don’t like to put any API keys in version control. It is easy to do when your newrelic.yml already has the api key in it and the docs for carrierwave say to just put your keys in the config initializer. I see this as a security concern as anyone who gets access to your repo immediately has all the tokens for everything.
Services like Heroku lean towards putting keys in your environment config. I really like this approach, but it makes things a little bit more complicated in development. I certainly don’t want to have to set up these keys in my zshrc.
One approach we’ve been trying out is to put all the application’s keys in a gitignore’d config/development.yml and load it when the application starts. We also put a development.example.yml next to it with all the keys that are expected but without the values so future developers know what they need to set up.
The setup is very easy. You start by editing your config/environment.rb and putting this code in to load the development.yml if it exists.
config.before_initialize do
dev = File.join(Rails.root, 'config', 'development.yml')
YAML.load(File.open(dev)).each do |key, value|
ENV[key.to_s] = value
end if File.exists?(dev)
endThen you can create your config/development.yml and fill it with all the keys you want to store in your server’s environment.
BRAINTREE_PUBLIC_KEY: big long key HOPTOAD_API_KEY: another big long key NEWRELIC_API_KEY: YABLK
Now comes a really important part. Be sure to add the development.yml to your .gitignore file. If you forget that, then all of this was for nothing.
config/development.yml
We changed an initializer so be sure to bounce your server at this point.
OK, now you can go ahead and start using those environment variable in your yml’s and initializers. For example, you can update your config/newrelic.yml with the key from the environment.
license_key: <%= ENV['NEWRELIC_API_KEY'] %>
And you can update your hoptoad configuration like so.
HoptoadNotifier.configure do |config| config.api_key = ENV['HOPTOAD_API_KEY'] end
Another added benefit is that you can very easily have different keys per environment, as opposed to hard-coding them and checking for the environment in the initializer.