Using Environment Variables to Safely Store API Credentials

By @zachfeldman
Written on Apr 7, 2014

As you begin to integrate third-party services into any application you’re building, you’ll probably need a set of “keys to the castle”, the API key and/or secret to tell this third-party service you are who you say you are.

You’ve been doing everything right and committing all of your code to a Git repository locally. Maybe you’ve also pushed your work publicly to GitHub. This is where the problem lies!

Let’s say that you’re configuring OmniAuth to use Twitter as a login option with your Twitter credentials (API key + secret):

1
2
3
4
Rails.application.config.middleware.use OmniAuth::Builder do #note: not a valid key and secret, just a random string of letters and numbers for argument's sake provider :twitter, "fj289y39yf832y8f3y289f2", "jf30f023u0932f33" end

Once you make your next commit, you’ve just committed your key and secret and potentially pushed it to GitHub for the whole world to see. Now anybody’s application can access Twitter on your behalf and even more importantly, if they have tokens for your users, they can access their private information!

To prevent this, we should store any sensitive information inĀ environment variables. Environment variables are kind of like variables in our program, except that they exist system-wide. You set them in one place and then you can use them inside of any running program on your computer. If you put that program on another computer, for instance when you deploy your application to Heroku or Amazon Web Services, you’ll need to set the environment variables on the machine your app ends up on on Heroku or AWS as well since they need to exist wherever a copy of your app is running.

To set environment variables locally, you can place them inside of your .bash_profile file. This file is a collection of settings you’d like to use when using bash, the default terminal access application. When you open up Terminal on OS X or Git Bash on Windows, you’re using a form of bash by default.

You can open your .bashprofile file using Sublime Text 2’s “subl ” command. If you haven’t set it up, check out <a href=“https://www.sublimetext.com/docs/2/osxcommandline.html”>this article. Your .bashprofile file is a plaintext file located in your main user directory (/Users/zachfeldman/ for me). Remember that your main user directory is aliased to ~, so you could open it up with the following command:

1
subl ~/.bash_profile

Once the file is open, you can program in your environment variables like so:

1
export TWITTER_KEY=fjioej32if290320u9f2309uf32

Once the file has been saved, you’ll need to source it in the currently open window for the environment variable to work in your current session:

1
source ~/.bash_profile

In any new session that you open (new terminal windows), the environment variable will be sourced automatically because ~/.bash_profile is sourced by default when a new session is open.

To use your new environment variable inside of a Ruby program, you can use the ENV constant, which is a hash of all of the environment variables on the system. For instance, to access the environment variable set above inside a Ruby program, I would use:

1
ENV['TWITTER_KEY']

And to use it in the OmniAuth example I inscribed above:

1
2
3
Rails.application.config.middleware.use OmniAuth::Builder do provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET'] end

Never commit your API keys or any other secrets to source unless there’s an incredibly compelling reason to do so! Have fun out there and be safe.

X-posted from the New York Code + Design Academy blog.





Sign up for our e-mail list to hear about new posts.