Dan Levy's Avatar DanLevy.net

Protecting Your Tokens, API Keys and Secrets

Public? Private? Wat?

Protecting Your Tokens, API Keys and Secrets

When to protect your tokens?

Securing API keys & tokens is critically important!

One mistake can lead to lost control of your server and data to hackers!

It shouldn’t be so difficult determining if any particular token must be hidden - even based on official documentation!

It is often made worse with the soup of related terms you’ll encounter: tokens, keys, credentials, secrets, private, and public.

Let’s re-frame this as between secret and non-secret.



🔒 Secret keys

** ‼️ Important:** Secret keys MUST be ignored by Git AND omitted in all browser code. How to use dotenv


How do you know when you’re dealing with a Secret key?


👍 Rule-of-thumb: servers which return CORS errors lack browser support. It strongly indicates you MUST proxy the service, treating it as though secret.

👍 Rule-of-thumb: costly services should (almost) always be proxied or hidden.

👍 Rule-of-thumb: if you do a write operation (file upload, insert db row), you could be dealing with secret keys.


Use cases & features: Secret keys

Checklist: Handling Secrets Safely

Quick Overview

Complete the following steps to eliminate secrets from your code:

DON’T create a .env file on deployed servers. Use your hosting services’ (e.g. Heroku, Netlify, AWS EC2) provided environment variable management tool: e.g. dashboard or command line.

Related Article: Using dotenv securely in NodeJS


🌍 Non-secret keys

👍 Rule-of-thumb: whenever a key must be sent to the browser in code or inline (e.g. via a <script src="https://my-api/?apiKey=123-abc-456"> tag), it’s definitely a non-secret. A common example is Google Maps.


Use cases & features: Non-secret keys

✅ Handling Non-secrets:

It’s safe to hard-code non-secret (public) keys!

Make this easier to manage long term with a shared config.js for your app.

Example:

// config.js
module.exports = {
  googleMapsKey: '123-abc'
};
// load-map.js
const config = require('./config.js');
const key = config.googleMapsKey;
const src = `//maps.googleapis.com/maps/api/js?key=${key}`;
// ...

Note: There are other Use Cases for environment variables. Some I didn’t cover: CI/CD/testing, feature flags, and runtime configuration for special environments!

Edit on GitHubGitHub