An API key is in your public code

The free health check — or a stranger — finds an OpenAI, Anthropic or Stripe secret key, or a Supabase service-role key, inside a script your browser downloads.

Why it happens

The key was used from client-side code: a fetch inside a component, a configuration object, or an environment variable exposed with a public prefix like NEXT_PUBLIC_ or VITE_. Anything the browser can read, everyone can read.

How to tell

  • The free health check lists the kind of key and the file it sits in — never the value.
  • The provider's usage shows calls you did not make.
  • A variable with a public prefix holding a secret.

The fix

  1. Rotate the key at the provider now. The old one is public and stays public in caches.
  2. Move the call to the server: a route or a server action that holds the key.
  3. Never put a secret in a variable with a public prefix. The service-role key never belongs in a browser.

The prompt for your builder

Paste this into Lovable, Bolt, Cursor, Claude Code or whatever built the app. Replace anything in capitals. It never asks you to paste a secret into a chat; keys go into your host’s environment, by you.

Prompt for your builder
Find every place my client-side code uses an API key — OpenAI, Anthropic, Stripe secret, Supabase service role — or reads a secret from a NEXT_PUBLIC_ or VITE_ variable. Move each call behind a server route that reads the key from a server-only environment variable, update the components to call that route, and list the keys I must rotate.

How Keelnest catches it

The free health check reads your public scripts and names the kind of key it found, never the value. Cost Guard notices the usage that follows.

Know the moment this happens.

Keelnest watches your production app every five minutes and tells you in plain English what broke — with the fix. Free for your first app.

Related