2HAASStart a project
All posts

Tech Tips

Keep API keys out of your frontend and your repo

An API key in frontend code or a Git commit is a public key. Where secrets belong, how a backend proxy protects them, and what to do the moment one leaks.

The 2HAAS team2 min read

An API key is a password for a program. Whoever holds it can spend your quota, read your data or run up your bill. Keys leak in two predictable ways: they are shipped inside frontend code, or they are committed to a repository. Automated scanners find both within minutes.

Anything in the browser is public

A JavaScript bundle is a text file that anyone can download and read. Minification does not hide a key, and neither does an environment variable. Build tools copy public variables, such as those starting with VITE_ or NEXT_PUBLIC_, straight into the bundle.

If a key must stay secret, it cannot be in the frontend.

Put a backend between the browser and the API

The frontend calls your server. Your server adds the key and calls the third party.

// server.js: the key never leaves the server
app.get("/api/weather", async (req, res) => {
  const city = String(req.query.city ?? "").slice(0, 80);
  const upstream = await fetch(
    `https://api.weather.example/v1/current?q=${encodeURIComponent(city)}`,
    { headers: { Authorization: `Bearer ${process.env.WEATHER_API_KEY}` } },
  );
  res.status(upstream.status).json(await upstream.json());
});
// In the browser: no key anywhere
const weather = await fetch("/api/weather?city=Dhaka").then((res) => res.json());

Add rate limiting and caching to that route. Otherwise it becomes a free relay for anyone who finds it.

Keep keys out of Git

  • Put local secrets in a .env file and list it in .gitignore.
  • Commit a .env.example that holds the variable names with empty values.
  • Turn on secret scanning with push protection in your repository host, or run a scanner such as gitleaks before each commit.

Store them properly in production

Use the secret storage your platform provides, or a dedicated secret manager. Do not bake keys into Docker images, and do not print them in CI logs.

Limit what each key can do

  • Least privilege. A key that only reads should not be able to write.
  • Restrictions. Where the provider allows it, lock a key to your domains or IP addresses.
  • Separation. Use different keys for development, staging and production, and for each service.
  • Alerts. Set a quota or a budget alarm, so misuse is noticed in hours and not at the end of the month.

Rotate

Replace keys on a schedule and whenever someone with access leaves the team. If rotation is rare, it becomes frightening. If it is routine, it takes minutes.

If a key leaks

  1. Revoke it at once. Deleting the commit is not enough. The key lives on in the history, in forks and in the scanners' databases.
  2. Issue a new key and deploy it.
  3. Check the provider's usage logs for activity that was not yours.
  4. Find out how it got there, and add the scanning that would have stopped it.

Keys that are meant to be public

Some keys are designed to appear in client code: a payment provider's publishable key, or a maps key. They are safe only because they are restricted. Apply the domain restrictions and usage limits the provider offers.

For loading configuration correctly, see environment variables in Node.js and Vite.

Keep reading

  1. Tech Tips2 min read

    Structured logging: make your logs searchable

    Plain text logs are easy to write and painful to search. Structured JSON logs with levels and consistent fields turn finding one failed order into a single query.

  2. Tech Tips2 min read

    Dependency hygiene: audit, update and prune npm packages

    Outdated and unused packages are a security risk and a tax on every install. A short routine with npm audit, npm outdated and a cleanup tool keeps a project healthy.

  3. Tech Tips2 min read

    Async error handling in JavaScript: try/catch done right

    Unhandled promise rejections crash Node.js services and leave browser apps quietly broken. Catch async errors with try/catch, .catch and a global safety net.

Tell us what’s in the way.

A few lines is enough. You get a candid yes, a candid no, or a sharper question.

  • Working software in week four
  • A reply in one business day
  • Handover is the deliverable

Prefer email? [email protected]

The problem, who it is for, and what is in the way right now.

One business day to a real reply. No sales sequence, no call required.