DEV Community

Cover image for Stop Hard-Coding API Keys: Why You Need Environment Variables Right Now
Jordan Rudman
Jordan Rudman

Posted on

Stop Hard-Coding API Keys: Why You Need Environment Variables Right Now

Have you ever built a project using an API that you wanted to post in a public repository so that you can share your code with the world? Perhaps you hard-coded in your API key and called it good. Well, did you know that there are malicious actors out there who use tools to scan public repositories for API keys? Without the proper security measures, they can have access to your secret key and do a number of things with it, including shutting down your service entirely. But no need to fear, environment variables are here to save the day!

Step 1: Create a .env File

In your project folder, create a file called .env at the same level as your /src directory. Inside this file, you’ll store your API key. The standard naming convention is all caps with words separated by underscores. If you're using React, the name must start with REACT_APP_. Here’s what a valid .env file can look like:

API_KEY=your_api_key_here
Enter fullscreen mode Exit fullscreen mode
REACT_APP_API_KEY=your_react_api_key_here
Enter fullscreen mode Exit fullscreen mode

Step 2: Access the Environment Variable

Next, in the file where you want to use the API key, create a variable that references your .env file like this:

const apiKey = process.env.REACT_APP_API_KEY;
Enter fullscreen mode Exit fullscreen mode

Now you can use the apiKey variable to represent your API key while keeping it hidden.

Step 3: Add .env to .gitignore

Finally, ensure your .env file is not uploaded to your repository by adding it to your .gitignore file:

.gitignore

.env
Enter fullscreen mode Exit fullscreen mode

Pro Tips:

  • Restart Your Development Server: Remember to restart your development server after making changes to your .env file. Otherwise, your changes won’t take effect!
  • Frontend Security Limitation: While .env files are great for hiding keys during development, remember that environment variables used in React are embedded in the build and can be accessed by anyone who inspects the client-side code. For truly sensitive keys, consider using a backend server to handle API requests.

Example Usage:

Here’s how you might use the apiKey variable in an API call with fetch:

const fetchData = async () => {
  const apiKey = process.env.REACT_APP_API_KEY;
  const response = await fetch(`https://api.example.com/data?api_key=${apiKey}`);
  const data = await response.json();
  console.log(data);
};
Enter fullscreen mode Exit fullscreen mode

Wrap-up

And just like that, your API keys are safe and you may share your code online without worry. Give it a try in your next project and let me know how it goes! Do you have another good way of hiding API keys? Share it down below- I’d love to hear your thoughts!

Top comments (9)

Collapse
 
manchicken profile image
Mike Stemle • Edited

Folks should stop using environment variables for secrets, this is bad advice. Each and every process has environment variables loaded into process memory at predictable locations, making it easy for attackers to find with a number of different vulnerability classes.

If you put your password/token/key into environment variables, they are not "safe," they're just slightly safer than when you put them in version control.

A better approach is to use a tool like AWS SecretsManager, 1Password APIs, or even BitWarden to store them encrypted, and only fetch them when you need them. After using them.

Compromised secrets remain a leading cause of breaches, including Ransomware. We should all do more to protect our secrets.

Collapse
 
webjose profile image
José Pablo Ramírez Vargas

A perfect follow-up article would be: Stop using archaic .env files: Why you need hierarchical configuration systems right now.

Collapse
 
joelbonetr profile image
JoelBonetR 🥇

Both approaches have their use cases IMHO. The biggest advantage I can see in hierarchical config is the ability to fetch from secret vaults in real time rather than having to store multiple tokens and what not in the MacBook of each developer, which on it's own can be an attack vector.

Collapse
 
webjose profile image
José Pablo Ramírez Vargas

It's just a plain text file, just like a .json file. The problem is perpetuating the concept of "an environment" in the browser. This artificial construct is unneeded. The whole dotenv is unneeded, even in NodeJS where there is an environment. Hierarchical configurations are much more versatile in every way. It is just dumb to keep .env files around.

Thread Thread
 
joelbonetr profile image
JoelBonetR 🥇

Aren't the hierarchical config files not "around" somewhere as well? Hocon, json... Who cares. Even if you store these in the DB (which is probably the most common way to implement a hierarchical configuration system) you'll have the migration or script to spin up a new environment based off of that given config, and none should be present in your repo or exposed to the public.

For a project (no matter how big) that doesn't need many configurations a dotenv is just fine, same goes for small projects which entire config is a handful of tokens and a flag.

Each and every tool has its pros and cons, glorifying a tool or applying the golden hammer approach only leads to dramas 😂

Thread Thread
 
webjose profile image
José Pablo Ramírez Vargas

It is "finer" to not use .env at all.

import config from './config.json';
Enter fullscreen mode Exit fullscreen mode

That's it. Why .env that forces you to install a BIG package like dotenv? How is that better?

Thread Thread
 
joelbonetr profile image
JoelBonetR 🥇

.env files are natively supported since long ago... Also

const BASE_URL = process.env.BASE_URL;
Enter fullscreen mode Exit fullscreen mode

isn't bad, either.

PS: env files are read on startup so make sure you restart the server when making changes there.

Thread Thread
 
webjose profile image
José Pablo Ramírez Vargas

That wasn't long ago, and that's only in NodeJS. In browser projects are still a hack.

Collapse
 
xwero profile image
david duymelinck

For truly sensitive keys, consider using a backend server to handle API requests.

All key are sensitive keys in a production environment.