Securing API keys
Rob Galanakis on May 11, 2023
I recently ran across an article titled The Safest Way To Hide Your API Keys When Using React in the usually-excellent TLDR Newsletter. The article explains:
Think of API keys as secret passwords that prove to the provider that it is you or your app that’s attempting to access the API.
So keeping API keys secure is extremely important!
The article falls victim to some common misconceptions and misunderstandings about APIs and security. Given the experience we have building WebhookDB (and everywhere else we've worked), I thought it'd be valuable to address the misunderstandings and offer an actual set of best practices for frontend developers who need to use APIs.
Misconception #1: You can "hide" API keys in the frontend
Here's the first problem: nothing you send to the frontend is hidden. You should assume that anything you send to the frontend (whether a browser, native app, or desktop client) can be read as plain text. You can obfuscate the key (perhaps by encrypting it with another key, which must be unencrypted), but cannot secure it. This is known as security through obscurity.
Misconception #2: All environment variables are equal
When a React application is built, it reads environment variables
and can write them into the built files. These built files cannot change
(this is why it's a "static" application). They get served publicly,
so they should never contain private API keys. This is why various frameworks
require you to prefix environment variables with
REACT_APP_ or similar;
it prevents accidentally embedding sensitive values into your built files.
dangerouslySetInnerHTML, it is a convention so you don't forget
what you're doing. See this issue for more explanation.
Misconception #3: Don't put .env files into version control
.env files are used to store environment variables. Sometimes they are checked in,
sometimes they're not, sometimes both (you'll see
.env in source control but an
.env.local file in
Many teams with private repositories will often check in
.env.development, etc) files with API keys for non-production accounts in them (like Stripe test environment keys). This avoids the situation where a team of developers are constantly DMing around keys. Why is this okay? Because if someone has access to these keys, they also have your source code, which would be a much bigger problem.
Keep in mind that you almost never want to commit production or infrastructure/CI keys in
.env files, and if you have a public repository, it should never have API keys in
.env files (find some other way, like a shared 1Password vault, to exchange development keys).
Misconception #4: Use a Proxy to hide API keys
The article mentions a "backend proxy server" as a way to hide API keys.
Instead of directly accessing the API from the front end, the front end sends a request to the back-end proxy server; the proxy server then retrieves the API key and makes the request to the API.
If a server just passes through a frontend request to some other API, it would still allow arbitrary API calls. The fact that the frontend doesn't have the actual API key is irrelevant. Proxies can't be used to protect API keys.
Misconception #5: Key Management Services are for APIs
A Key Management Service (KMS) is generally used on the infrastructure and application data encryption side, for example to manage the cryptographic keys that encrypt your database at rest.
To store API keys, you generally will use "secrets management" or "configuration management." This could be AWS Parameter Store, Heroku Config Vars, Hashicorp Vault, Netlify Build Environment, etc. Usually the idea is that whatever builds your frontend application (or runs your backend server) reads from the secrets manager and injects the variables into environment variables. You can also read the secret store directly from your application, though this is rarely ideal.
Importantly, because what's in the frontend is never "secret",
you may not even need secrets management. You may be able to get by
.env files in private version control.
Misconception #6: All API keys are the same
Some APIs keys, like for Google Maps or parts of Stripe, are designed to be called from frontends. I have never seen a name for this sort of thing, but perhaps "public API keys" or "publishable API keys" are a good name.
These API keys can be embedded into your frontend. It's always possible to restrict them to some degree, like being used from specific domains or able to call certain API endpoints.
Misconception #7: Keeping API keys safe is easy. Or hard.
It turns out that keeping API keys safe is easy, because you just need to keep two things in mind:
- Non-public API keys should always be hidden.
- Anything on the frontend cannot effectively be hidden.
It follows, then, that if your frontend needs to make calls using an API key, you need a server of some sort (it can be anything from a No Code function to a totally custom application, but there has to be a server).
More on high-quality API integrations
If this article was useful, you may enjoy our FREE checklist for high-quality API integrations.
It covers everything you'll need to think about before going live with an API integration, including correctness, security, performance, and maintainability concerns.
We hope you'll check it out and let us know what you think.
Recent Blog Posts
May 4, 2023
Ensure a smooth launch of your integrations with 3rd party APIs using our checklist.Read More →
April 17, 2023
Learn about our new transparent and affordable pricing tiers.Read More →
April 10, 2023
Most APIs we use every day are not your Stripes or Shopifys. These are the API 99%.Read More →
April 6, 2023
How does WebhookDB compare to other projects that bridge the AWS API with SQL?Read More →