Protecting APIs keys on Git-hosted Ruby project - ruby

I'm not really sure where to start with this. I'm making a Ruby project that interfaces with a dictionary API, and uses an API key. I don't want anybody and his uncle to be able to see this key, but the project will have to be hosted on GitHub. How can I go about doing this, and accessing the key from the Ruby program?
Clarification: this is for a class, and we have to use GitHub

Normally, you'd put such things in a file like this:
DICTIONARY_API=key_goes_here
and check in a version of the file (named .example or .sample or something) which just contains blanks:
DICTIONARY_API=
Or you could read the key from the environment, using ENV. If you host on Heroku, this is recommended. See also the Dotenv gem and the ENVied gem.
I've seen both methods combined (especially when using Dotenv) by making a .env file for local/non-heroku usage, and using Heroku's config settings on Heroku.

Use the Figaro gem. Documentation
Basically you will use a file called application.yml and store environmental variables. Double check that application.yml is listed in your .gitignore file so nobody can view it on github.
You could set:
# application.yml
API_KEY: my_api_key_here
And then you could set it to another variable in your app with:
# anywhere in your app
api_key = ENV['API_KEY']
For production, you can use Figaro's commands to sync your env variables with Heroku.

Related

How can I change the database name according to the database credentials provided by heroku during production?

Heroku provides its own database name and other credentials, but my local database name is different.How can I change the database name according to the database credentials provided by heroku during production?
Use a package like dotenv. dotenv and variants of it likely exist for whatever language you're using.
Basically, you want to use environment variables instead of hard coding values into your code. So, instead of writing something like this:
my_database_connect('my_username', 'abc123')
You'd write:
my_database_connect(process.env.DB_USERNAME, process.env.DB_PASSWORD)
Heroku will already have these environment variables set on the "config" tab of your app. Then for local development, you'll create a file called .env and have this text in it:
DB_USERNAME=my_username
DB_PASSWORD=abc123
Don't commit .env to your git repository – it should only live on your machine where you develop. Now your code will run locally as well as on Heroku, and connect to the proper database depending on the environment it's running in.
Here's an article that explains this more thoroughly for node.js, although this is basically the best practice for general development: https://medium.com/#rafaelvidaurre/managing-environment-variables-in-node-js-2cb45a55195f
First I created an application name on Heroku. Then I deployed my app to heroku by connecting to github.
Heroku provides the database credentials after we deploy our applications. Then I redeployed the app through github by changing the configuration in application.properties file as follows:
#localhost configuration
SPRING_DATASOURCE_DRIVER_CLASS_NAME=org.postgresql.Driver
SPRING_DATASOURCE_URL=jdbc:postgresql://localhost/transactions?useSSL=false
SPRING_DATASOURCE_USER=postgres
SPRING_DATASOURCE_PASSWORD=some_pass
#server database configuration
SPRING_DATASOURCE_DRIVER_CLASS_NAME=org.postgresql.Driver
SPRING_DATASOURCE_URL=jdbc:postgresql://ec2-23-23-247-222.compute-1.amazonaws.com/d6kk9c4s7onnu?useSSL=false
SPRING_DATASOURCE_USER=rimjvlxrdswwou
SPRING_DATASOURCE_PASSWORD=dd903753bc0adffb96ce541b1d55fb043472e32e28031ddc334175066aa42f69
Then you have to edit the config vars according to your application.properties files as shown in the figure below
config_var.png

How do I exclude my API KEY pushing to github?

if I exclude the file with API KEY and push to gitHub and then to Heroku the app doesn't work because the app can't get access to the api key.
What is the workaround? I'm quite a novice so comments or info with human readable language would be highly appreciated. Thanks!
You need to store the API key as an environment variable.
In heroku, go to your app, then settings and click on "Reveal Config Vars".
In there you can store your API key for your deployed server to use. This is also where you will store DB urls too, etc.
Heroku has interface for setting up environment variables.
So use environment variable locally (from environment or e.g. .env file) and remotely.
Also read on 12-factor-app
Usually this kind of stuff should be kept in Heroku config variables. I find heroku command line more convenience. You can download it here. Then, you can use this command to setup the new Heroku configVar at will.
heroku config:set API_KEY=1234567890 --app your_app_name
To see all configs,
heroku config --app your_app_name
Then, based on the language developed, you can access this configVar from code. For example, you can do this in Ruby on Rails' code.
<%= ENV["MY_API"] %>

Changing ENV variables in Heroku doesn't change them in Phoenix application

I have a Phoenix 1.2 application running on Heroku, with an ENV variable that sets the email addresses I wish to send email to.
When I change the environment variable's value, it doesn't seem to take; Only after I make a PR and redeploy does the new change seem to take.
This makes it seem like I need to "reload" the code or memory somehow. Thus, 2 questions:
Why is this occurring?
Any ideas on how to fix it?
I'm assuming you're setting your env values in config files and using Application.get_env to access them in your application.
Elixir applications are compiled, not interpreted. When you deploy your application to heroku, it compiles it with the available Environment Variables and they become hardcoded in to the app. So, even restarting the application would not work; it needs to be recompiled with the new environment variables.
Here are a few solutions:
You can use RELX_REPLACE_OS_VARS=true if you're using Exrm to build releases;
Use System.get_env for getting ENV variables instead, but this won't work unless the application is restarted after changing the environment configuration;
Use a simple wrapper module that lets you use environment configurations by specifying them like {:system, "MY_VARIABLE"} in config.exs;
Or use an existing package like Confex or Conform to manage your configurations

Sinatra Set Configuration File on Heroku

I have been struggling for the last couple hours with this question, and I hope someone can help me out. I'm creating my first Sinatra app and I would like to use Mongo as the backend. I have decided to use Heroku's MongoLab service, and it gave me a connection URI to use to connect with Mongo from within my Sinatra app. This does not seem like the type of info I want to keep in Version Control, but I'm having a hard time figuring out how to not hardcode it into the application. On one hand the key is stored permanently as a Heroku ENV var, but that does not help when I'm developing locally. I've tried creating a config file as outlined here: http://www.miqueloliete.com/configuring-environment-variables-in-sinatra/, but it only helps locally. I can't seem to find the way to do this.
Thanks in advance,
Ryan
There are many ways to achieve these so I can just give you ideas.
Env
You can set the enviroment variable on your local pc with export name=mongourl
configuration
Sinatra provide a way to use different configuration sections. That is what I do normaly. Like these:
configuration :development do
setup things to use your local db
end
configuration :production do
setup things for production db
end
config file
Store these informations in a yaml file.
I figured out the best way to do it for me. I didn't realize that in Ruby ENV['somevar'] accessed your environmental variables for your shell, so in order to not commit my secret keys and passwords to version control, I just make sure that all my environmental variables that I had in my Heroku (the results of heroku config) were also variables in my shell.
You can use the dotenv gem and then create a .env file locally that has the same keys as your Heroku ENV variables. That way you can keep the same environment keys in your code for both environments, and choose to have identical or different values, as needed.
#app.rb
require 'sinatra/base'
...
if Sinatra::Base.environment == :development
require 'dotenv'
Dotenv.load
end
#.env
DATABASE_URL=mongo_sinatra_connection_info

Is there a way to set a default app for Heroku Toolbelt?

I have more than one app/git remote at heroku and I would like to know if it is possible to configure a default application so that, whenever I forget to specify the app (--app), the toolbelt would use it.
You can set the heroku.remote key in your repo's Git config to the name of the default remote. For example, if your remote is called staging, you could do this:
$ git config heroku.remote staging
To see how this works, here is the relevant source.
For more, information about this, see Managing Multiple Environments for an App.
You could also go for:
heroku git:remote -a <name-of-the-app>
or if you tend to make a lot of mistakes in the configuration of wrong apps, you can use this library I made: https://github.com/kubek2k/heroshell
This is a Heroku wrapper shell that allows you to work in the context of a given Heroku application
You can set the HEROKU_APP environment variable.
Found this question while searching for it myself. The other answers refer to Heroku's old ruby-based CLI. The new JS CLI doesn't seem to support the same git-remote-reading feature. A quick search of the source code on GitHub found this.

Resources