Outrings
Security and email authentication

I found an API key in my HTML. What now?

Rotate first, investigate second. Then work out whether the key ever needed to be in the browser at all.

3 min read
Short answer

Assume it is compromised and rotate it immediately — anything served to a browser is public, regardless of obfuscation. Then check whether it needed to be there: some keys are designed to be public and restricted by origin, most are not.

Rotate first

Do not investigate before rotating. The key has been served to every visitor, every crawler and every archive that has fetched the page. It may be in the Wayback Machine and in search engine caches. Treat exposure as certain rather than probable.

  1. Generate a replacement key.
  2. Deploy the replacement wherever it is legitimately needed.
  3. Revoke the old one.
  4. Check the provider's access logs for use you do not recognise.
  5. Then work out how it got there.

Which keys are meant to be public

Key typePublic?Protection
Google Maps JavaScript keyYesRestrict by HTTP referrer and by API in the console.
Stripe publishable key (pk_)YesDesigned for the browser. It cannot move money.
Firebase web configYesSecurity comes from Firebase rules, not from hiding the config.
Analytics measurement IDsYesPublic by design.
Stripe secret key (sk_)NoRotate immediately. It can charge cards.
Database credentialsNoRotate, then audit access.
Cloud provider access keysNoRotate immediately. These get scanned for and abused within minutes.
Email or SMS API keysNoRotate. Abuse means your domain sends spam.

The rule underneath

Anything the browser receives is public. Minification does not hide it, base64 does not hide it, splitting it across variables does not hide it. Someone reading your bundle finds it in seconds, and automated scanners find it faster.

So a key in the browser must be one where being public is acceptable — restricted by origin, scoped to harmless operations, or rate-limited. If it is not, it belongs on the server, with your front-end calling your own endpoint instead.

How they get there

  • A build tool inlining the whole environment. Vite exposes anything prefixed VITE_; Next.js exposes anything prefixed NEXT_PUBLIC_. Putting a secret behind those prefixes publishes it.
  • A developer testing quickly with a hardcoded key and never coming back.
  • A server-side key imported into a file that is also bundled for the client.
  • Configuration written into a data attribute or an inline script tag by a template.
  • A committed .env, later removed but still present in git history — and readable if .git is exposed.
Check git history as well as the current tree. A key removed in a later commit remains in the repository, and if /.git/ is publicly readable — which is more common than it should be — the entire history including that key can be downloaded.

Preventing recurrence

  1. Add secret scanning to your pipeline. Most hosted git providers offer it, and there are good standalone scanners.
  2. Use a pre-commit hook that refuses commits containing credential-shaped strings.
  3. Keep a hard rule that server secrets never carry a public build prefix.
  4. Restrict every key that must be public — by origin, by API, by rate limit.
  5. Confirm /.git/ and /.env are not web-readable. They should return 404.

What our audit reports about this

Every item below is measured directly, not inferred. Run it against your own site and the result names the exact rule or header responsible.

  • Credential-shaped strings in HTML and inline scripts, reported redacted rather than in full.
  • Whether /.git/config, /.env and similar paths are publicly readable.
  • Every script loaded, with its origin, so third-party code is visible at a glance.
  • Whether findings appear only in your report — exposed secrets are never stored or included in aggregate statistics.

For agents and scripts, the same measurement is at /api/v1/security?url=yoursite.com — see the API documentation.

Related questions

Is a Google Maps key in my HTML a problem?

Only if it is unrestricted. It is designed to be public, but an unrestricted key can be used from any site and billed to you. Restrict it by HTTP referrer and to the specific APIs you use.

Can I obfuscate a key so it is safe?

No. Obfuscation delays a curious person by minutes and an automated scanner by nothing. If a key must not be public, it must not be in the browser.

How would I know if a key was abused?

Check the provider's usage logs for requests from origins or regions you do not recognise, and for spikes. Set billing alerts. For cloud provider keys, assume abuse begins within minutes of exposure — these are actively scanned for.

Read next

All 50 guides · How every check works · API for agents