Ruby Dotenv
Tags: ruby, security, api
Published: 2019-10-14 13:58:21

I recently submitted a Ruby CLI Portfolio project for the Online Software Engineering curriculum at [Flatiron](https://flatironschool.com/). If you are interesting you can read more [here](https://medium.com/@EclecticCoder/cli-ruby-gem-with-dark-sky-api-551e6ac02928), or go look at the course code on [GitHub](https://github.com/eclectic-coding/weather_ferret). The application used the [Dark Sky API](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=2ahUKEwjgxoKZ7JvlAhVrmuAKHdIBDCAQFjAAegQIBRAC&url=https%3A%2F%2Fdarksky.net%2Fdev&usg=AOvVaw10jFZ6mzy1Qmt5Q4t33SKa) to retrieve weather forecast and request me to use an API key. 

## The Problem  
The problem was that I had a review assessment and I did not want the reviewer to have to apply for an API key just to review the application. So, while developing I decided to temporarily to hard code the API key into the source code, at least until the review process was complete. 

### Options
In Ruby, like in most other programming languages, there are a few options to securing API keys:
- Encrypt and store in a file (YML, CSV, etc). 
- Encrypt and store in a Database.
- Using [attr_encrypted](https://github.com/attr-encrypted/attr_encrypted) 
- Use an ENV file which is used only in development

Since, I was not using a Database in this simple application I rules that option out, and decided to use DOTENV. I had some experience with this technology in React and [GatsbyJS](https://www.gatsbyjs.org/) projects, so it seemed to be a simple and effective solution. 

## Dotenv
So, I added the [DOTENV gem](https://github.com/bkeepers/dotenv) to implement this security strategy. In the project gemfile I added the following dependency:
```
spec.add_development_dependency 'dotenv', '~>2.7.5'
```

### ENV File
You will need to create a hidden file in the root of your project  named `.env`. This file will include the API key to use during development. You will want to att this file to your `.gitignore` file so it does NOT get pushed to your repository. 

In the `.env` file you will create a constant to hold you key:
```
DSKY_API_KEY=putyourkeyhere
```

###Setup 

You need require the gem early in the application bootstrap cycle. In my case, the [Request class](https://github.com/eclectic-coding/weather_ferret/blob/30a1e9d14b245e72b8caae04c8128969ad0ec4e6/lib/weather_ferret/request.rb#L4) called the API once. So, I add the following to require the gem:
```
require 'dotenv'
Dotenv.load('./.env')
```
Next, where the key was originally [hard coded](https://github.com/eclectic-coding/weather_ferret/blob/30a1e9d14b245e72b8caae04c8128969ad0ec4e6/lib/weather_ferret/request.rb#L26)


```
def self.fetch(location)
    coordinate_pts(location)
    ForecastIO.configure do |c|
      c.api_key = ENV['DSKY_API_KEY']
      c.default_params = { time: 600, exclude: 'minutely, hourly' }
    end
    @forecast = ForecastIO.forecast(@lat, @lon)
  end
```
Notice the use of `ENV['DSKY_API_KEY'] in place of the original API key.
So, that is pretty much it ... it works :bomb: :boom:

## Extra Security
For an extra security measure, I revoke my Dark Sky account so the API key that was in my commit hisoptry would be inactive. 

Hope this tutorial helps you and leave a commit of hit me up on Twitter.