Is your AI key exposed right now? The 10-minute check.

July 18, 2026

The most expensive AI bills don’t come from a clever hacker. They come from a valid key someone found and used. And it’s the scariest kind, because — as someone put it on my post this week — a leaked key walks past every gate you built. Your spend caps, your auth, your rate limits all assume the caller is you. A stolen-but-valid key is you, as far as your system can tell.

So before you build more gates, spend ten minutes making sure the key isn’t already lying in the open. Here’s where to look.

The seven places AI keys leak

Go through these on your own setup, now. Most take a minute each.

The scariest bill is a real key in a stranger's hands.

  1. Your frontend or mobile app. Anything shipped to the browser or the app store is readable by anyone — “hidden” in the code is not hidden. A model/API key must never be in client code. Open your app’s network tab or bundle and search for your key prefix (sk-, AIza, etc.). If it’s there, treat it as already leaked.
  2. A public repository. Search your GitHub/GitLab org for the key prefix. Even a repo you think is private may have been public once.
  3. Git history. A key removed from the current code often still sits in an old commit. Search the full history, not just the latest files.
  4. Logs. Do you log full request headers or bodies? Keys printed into application logs, access logs, or a logging service are readable by anyone who can read logs.
  5. Error messages. A stack trace or error response that echoes the request can leak the key to whoever triggers the error — sometimes the end user.
  6. Inside prompts. Keys pasted into prompt templates, system prompts, or tool definitions travel wherever the prompt travels, including to the model provider and any prompt logs.
  7. CI/CD and build logs. Secrets echoed during a build, or committed into a pipeline config, end up in build output that’s often more visible than you’d expect.

Catch it in one command

You don’t have to eyeball each place by hand. ripgrep can sweep your source, your built bundle, and your whole git history for the provider key formats in a couple of lines:

# One pass over everything a stranger (or a browser) could read: your source tree AND the
# built bundle. dist/ is usually gitignored, so --no-ignore is what reaches into it.
rg --no-ignore --no-heading -o -E \
  'sk-ant-[A-Za-z0-9_-]{20,}|sk-[A-Za-z0-9-]{20,}|AIza[0-9A-Za-z_-]{35}' . 2>/dev/null
#   sk-ant-… → Anthropic     sk-… → OpenAI     AIza… → Google API key

# Same patterns across the full git history — a key you "removed" often still sits in an old commit:
git log -p --all | rg -o -E 'sk-ant-[A-Za-z0-9_-]{20,}|sk-[A-Za-z0-9-]{20,}|AIza[0-9A-Za-z_-]{35}'

The first command scans your working tree and the shipped dist/ bundle in one pass; the second walks every commit, where “deleted” keys love to hide. If a match turns up inside your built bundle or any client-side JS, treat that key as already public — anything the browser downloads is readable by everyone who loads your page. The fix is always the same: the key belongs server-side, behind your own backend or gateway, and must never be compiled into what you ship to the client.

If you find one — the order matters

Don’t just delete it from the code. Do this, in order:

  1. Rotate it first. Generate a new key and revoke the old one at the provider. Deleting it from your repo does nothing if a copy is already out there — only revoking stops it.
  2. Move it server-side. The key belongs in a server environment variable or a secrets manager, never in anything shipped to a client. Route model calls through your own backend so the key never leaves your servers. (the $55k version of this mistake)
  3. Restrict it. Limit the key to only the APIs and, where possible, the origins it actually needs. A key that can only reach one endpoint is far less dangerous if it leaks again.
  4. Cap it. Give the key its own spend ceiling, so even a valid, authorized key can’t run past its own budget. This is the layer that contains a leak you didn’t catch — the key still looks like you, but it hits a wall at its number instead of your whole account.

Why the cap is the part people skip

Steps 1–3 are hygiene. Step 4 is the safety net, and it’s the one most teams don’t have. Auth tells you who is calling; it does nothing to stop an authorized caller from spending too much. A per-identity hard cap is what turns “a leaked key emptied my account” into “a leaked key burned its own small budget and tripped.” Same leak, very different Monday.


If you want a second set of eyes on where your keys live and whether a leaked one could actually run up your bill, that’s a quick thing for me to check. It’s just me, so it comes straight to me and I reply fast. Send me your setup and I’ll tell you which keys are exposed or over-privileged, and where you’re missing the per-key cap that would contain a leak — free, within a business day.

Free live workshop: cap your AI spend (Oct 8)

A hands-on 90-minute session — wire a fail-closed spend cap + cost-aware rate limiting against a real stack, live, so a leaked key or runaway agent can't run up your bill. Full details & times → Save your seat (and get each new lesson as it lands):

Double opt-in — one email to confirm. The lessons are free; the course is optional. No spam, unsubscribe anytime.