Best practices for working with API keys in the frontend

Ever wondered if it’s ok to have your API key bundled with the frontend, public for anyone who uses your app to see?
You know you should never put secrets in the UI. But then you see people bundling their keys with the UI all the time (Firebase API key, anyone? 😀)

So how can you tell what to do in your case?
This article aims to shed some light on how you can decide for yourself.

Be aware that there are no secrets in the frontend

Before moving on to more specific advice, it’s good to get one thing clear first: there are no secrets in the UI.

Your frontend, after being compiled, is really just a bunch of HTML, Javascript and CSS files.
And if there is any key that the UI needs, it’s usually just hardcoded as a variable in the Javascript code.
This means that someone can inspect all the global variables your have in memory and track down the key.

But they don’t usually need to go such lengths - the keys are usually used to call APIs, so it’s enough to open the Network tab to see what request parameters or request headers are sent and figure out the keys!

Consider whether your API keys can be public or not

In general, you never want to share your API keys. This means you should only use your keys from the backend, where they are not accesible publicly.

However, there are some exceptions to this.

Some keys don’t give access to any resources, but instead act as an “ID” that associates you or your application to a certain user account. A good example of this is the Firebase API key - the docs explicitly say it’s ok to include this key in your code:

Usually, you need to fastidiously guard API keys (for example, by using a vault service or setting the keys as environment variables); however, API keys for Firebase services are ok to include in code or checked-in config files. source

Another exception could be for keys that only give access to public resources. Even if there is a risk that the key is compromised, the risk is very low - if anyone can get their own key for free, why would they steal yours? A good example of this is the Movie Database API - it’s not ideal to have the key public, but the risk is also very low.

Lastly, it could be ok to have your key in the UI if you setup some extra guards in place. Two common strategies are to only limit the usage of the key to requests coming from a certain domain and to setup restrictive quotas to prevent brute force attacks.

Don’t commit your secrets to git

If you’ve decided it’s ok to use your key in the frontend, don’t just include it in your code! Instead, extract it as a build-time environment variable.

This will allow you to configure the key based on different environments (staging/production etc.) and also make it a bit harder for someone to steal.

To achieve this, you’d usually have a file containing the app configuration (usually called .env), that you don’t commit to git (by ignoring it in your .gitignore file) and whose values you can access in your app as Node environment variables - process.env.SOME_API_KEY.

If you’re using Webpack, you can setup dotenv and the dotenv-webpack plugin to get this to work. If you’re using CRA, you get it out of the box.

Conclusion

I hope you found this overview useful. Do share your thoughts in the comments below if you have any feedback or questions!