In this post, I’ll address how I like to store and use my API keys.
Introduction
When using computer software to access secured resources or services, typically over the internet, the software usually requires an API key. The API key is like a password the software to authenticate itself to the resource or service. As an example, I’m a TA for a data science class where we use Github to manage students’ homework assignments. For each homework assignment, each student gets their own private repository that only they and the course staff can see. In order to create and push those repositories, the script I use, Teacher’s pet needs to authenticate itself to Github, and the way it does so is via an API key.
Bad ways to store API Keys
Technically, API keys should be treated like passwords, because if someone has your API key, they could potentially perform operations without your permission. In the case of the data science TA example, an unauthorized user could delete all the students’ homework repositories. Here are some downsides of some common ways API keys are stored:
Environment variables: The drawback of this approach is that environment variables are visible to every program on your computer, and a malicious program could publicize these. Additionally, people sometimes initialize these environment variables in their
bashrc
file, which is an unencrypted file—if you wouldn’t store your password in an unencrypted file, why store your API key that way?Directly within your code: This is a big no-no, especially if you’re going to push your code to a public Github repository. If you accidentally push your API key, you’ll need to fully delete it from your history using something like bfg, or other people will be able to see it.
Using a password manager for API Keys
A lot of programs allow you to pass in the API key as a command line argument.
If you’re writing your own program that requires an API key, make it take the
API key as a command line argument instead of hard coding it in—this makes it
harder for you to accidentally push the API key to Github. (NB: To parse command
line arguments, you can use the
optparse for R and
argparse for Python).
Therefore, you can store your API key in a password manager and copy/paste it
when you call your program. The password manager will encrypt the API key so
it’s more secure than storing it in an unencrypted file or your bashrc
.
Additionally, if you’re worried about your bash history being saved (in a
plaintext file no less), you can prevent certain entries from being recorded.
This Stackoverflow
post
has solutions for both bash
and zsh
.
Finally, if you can interface with your password manager on the command line, you can forgo the copy/paste step by passing the output of the password decryption step as a command line argument, using command substitution. Here’s an example using the pass password manager:
my_command --apikey=$(pass show api_key/Github)