Skip to content

Secrets

Secrets are any pieces of information you don't want to store directly in your code. Generally, this includes passwords and other credentials for logging into third-party applications. If you need to provide a password to sign into a database, how do you make the password available without storing it in the code itself?

The secrets/ folder

I add a secrets/ folder to my projects and save credentials there as JSON files. MAKE SURE TO INCLUDE secrets/ IN YOUR .gitignore FILE (but add a .keep file)!

Here's what a my_secrets_file.json file would look like with a secret key:

{
    "USERNAME": "<save_key_here>",
    "PASSWORD": "<save_password_here"
}

Note that JSON files require double quotes.

Accessing secrets

You can read that into python just like a dictionary:

import json

with open('secrets/my_secrets_file.json') as f:
    my_creds = json.load(f)

USERNAME = my_creds.get("USERNAME")
PASSWORD = my_creds.get("PASSWORD")

Don't commit secrets

When you create the secrets/ folder, go ahead and add it to your .gitignore file, even before you save anything there, so you don't forget. Add a .keep file so that collaborators know that there are credentials required for this project. Add these lines to the .gitignore file:

secrets/*
!secrets/.keep

If you want, you can save the structure of the credentials in the .keep file to help collaborators set it up correctly (obviously don't actually put the secret info here):

- my_secrets_file.json:
{
    "USERNAME": "<save_key_here>",
    "PASSWORD": "<save_password_here"
}

- credentials.json:
...

Remove secrets from Github

You will, sooner or later, commit a secret to GitHub. GitHub (or the third-party app) may even email you right after you did it (e.g., Google will email you if you commit google credentials to GitHub). To remove the file, use git rm -r --cached <filename>. Then commit and push the changes to GitHub.

Auth packages

Some packages such as google-auth or oauthlib access and use credentials stored as a JSON file.

Environment Variables

Another way to store secrets is to use environment variables. You will need to use environment variables (rather than JSON files) with some platforms like Heroku. Here's how you can structure code to seamlessly transition between local testing and production:

# Local dev
try:
    with open('secrets/passwords.json') as f:
        VALID_USERNAME_PASSWORD_PAIRS = json.load(f)
# Heroku dev
except:
    json_creds = os.environ.get("VALID_USERNAME_PASSWORD_PAIRS")
    VALID_USERNAME_PASSWORD_PAIRS = json.loads(json_creds)