API Key Leak Check: How to Find Exposed Keys (2026)
Short answer: run three checks. Scan every repo and its full history with TruffleHog or Gitleaks (for example
trufflehog git file://. --results=verified), then read your provider's usage and billing pages for spend you don't recognize, then watch for provider-side signals: Google blocks exposed Gemini keys automatically and OpenRouter emails you when GitHub detects your key. If a check finds something, revoke it before you clean anything up. A clean scan is evidence, not proof.
Keys leak quietly. Nothing crashes, no email arrives, and the bill comes at the end of the month. GitGuardian's State of Secrets Sprawl 2026 report, published in March 2026, counted about 29 million secrets newly exposed in public GitHub commits in 2025. AI-service keys made up 1,275,105 of them, an 81% jump over 2024. One incident in the report involved 113,000 leaked DeepSeek API keys sitting in public for hours before anyone noticed.
If you run your keys through a BYOK chat app, your exposure surface is wider than a repo. The key passes through a paste dialog, an encrypted vault or your browser's local storage, and whatever screenshots you took along the way. This post covers where AI API keys actually leak, the three passes of a proper leak check, and the order of operations when one of them hits. For the per-provider revocation clicks, see the API key revocation guide.
Where AI API keys leak
| Vector | The usual mistake | Caught by |
|---|---|---|
| Git repo + history | .env committed once, deleted later | TruffleHog, Gitleaks, GitHub secret scanning |
| CI logs | Key printed by a debug step or an error dump | Log search (manual) |
| Client-side code | Key shipped in a JS bundle or mobile app | Bundle scan, runtime scanner |
| Screenshots & support threads | Key visible in a console screenshot | Nothing automated |
| Shared devices | Key in local browser storage on a machine you lend | Nothing automated |
| Pastes & chat logs | Key pasted into a gist, Discord, or a ticket | Public exposure sweeps |
The repo row is the one that catches most people. Deleting a file in a new
commit removes it from the working tree and leaves it in history, where
git log -p will happily print it years later. Gitleaks uses exactly that
command under the hood to scan patches, which is why a history scan finds
things a folder scan misses.
Pass 1: scan your code and its history
Two tools cover almost everything here, both free and open source.
TruffleHog scans git history and verifies whether a found credential still works, so you know which findings are fires and which are old ashes:
trufflehog git file://. --results=verified
Gitleaks scans patches across the repo history and is the more common choice for blocking new leaks before they land:
gitleaks git -v
Run both once, by hand. Then wire Gitleaks' pre-commit hook into your workflow so the next leak stops at the commit instead of reaching GitHub. Scan the private repos too. A private repo that later goes public, or that invites a contractor, is a public repo with extra steps.
One trap worth naming: never paste your actual key into a "check if this key leaked" website. You would be performing the leak you were checking for. Scanners run locally on your machine for a reason.
Pass 2: read your provider's usage pages
The fastest leak signal is not a scanner. It is a charge you don't recognize. Open the usage and billing page for every provider key you hold and look at the last 30 days: request volume by day, models used, and spend. A key used while you were asleep, calling a model you never picked, is a leak until proven otherwise.
This check works because API keys are bearer credentials: whoever holds the string can spend your money, with no second factor. Google's own documentation makes the point bluntly in its API key guidance: the key "is all that is needed to make a call."
Do this pass even when your repo scan comes back clean. Not every leaked key came from a repo.
Pass 3: let the platforms tell you
Some of this detection runs whether you opt in or not:
- GitHub secret scanning watches public repos for known key formats and notifies the vendor. Many vendors then notify you.
- Google proactively blocks Gemini API keys it detects as publicly exposed. A blocked key shows up as sudden permission errors in your app. The Google setup guide covers restricting a replacement key to the Generative Language API and to specific IPs or referrers.
- OpenRouter participates in GitHub's secret-scanning partner program and emails you when your key turns up in a public repo. Treat that email as a same-day task.
If a provider offers extra key restrictions, turn them on. Google keys can be restricted to the Generative Language API and to specific IPs or referrers; OpenAI supports IP allowlisting on project keys; OpenRouter keys carry their own credit caps. A restricted key is a leak with a smaller blast radius. The storage side of the same question is covered in local vs hosted API key storage.
What to do when a check finds a key
The order matters more than the speed.
- Revoke first. Delete or disable the key in the provider console. Per-provider steps are in the revocation guide. Google is the one exception on ordering: create the replacement, move your app to it, then kill the old key, to avoid downtime.
- Replace it with a new key, named for the app that will hold it.
- Audit usage and billing for the exposed window. Note the first and last suspicious timestamps before you file anything.
- Then clean up the source: purge the file from git history, rotate anything that shared a commit with it, fix the process that let it in.
People reverse steps 1 and 4 because cleaning the repo feels like fixing the problem. It is not. History rewriting does not reach copies already cloned, forked, or cached. The revocation is the only action that ends the risk; everything else reduces the chance of a repeat.
What a leak check cannot see
No scan covers everything, and pretending otherwise is how people talk themselves out of rotating a key they feel uneasy about. These checks cannot see:
- Keys that leaked in a DM, an email thread, or a private screenshot.
- Copies taken from a hosted vault in a breach you never heard about.
- Keys held by a browser extension or a shared machine's local storage.
Which is why the honest reading of "my scan came back clean" is "no public exposure found today." Rotate anything that feels wrong anyway. Anthropic's own guidance suggests rotating on a schedule, roughly every 90 days, and using separate keys for development and production so one leak stays one compartment. The threat model behind these trade-offs is in is it safe to give an AI app your API key.
Which check should you run first?
| If you… | Start with | Time |
|---|---|---|
| Have no idea whether anything leaked | Provider usage pages (pass 2) | 5 min |
Have ever committed a .env | TruffleHog history scan (pass 1) | 10 min |
| Got an email from OpenRouter or GitHub | Revoke now, audit after | 2 min |
| Share a laptop or use local key storage | Rotate + check the shared machine | 15 min |
| Run a small team with one key per dev | All of the above, per key | 30 min |
FAQ
How do I check if my API key is leaked? Run a history scan with TruffleHog or Gitleaks, read your provider's usage page for unfamiliar traffic, and watch for provider notifications (Google blocks exposed Gemini keys; OpenRouter emails you). If you cannot account for a usage spike, treat the key as leaked and rotate it.
Can I check a key by pasting it into a scanner website? No, and doing so creates the exposure you were checking for. Run scanners locally. TruffleHog and Gitleaks both read your code and history on your own machine.
Does deleting a leaked file from my repo fix the leak? No. The old commit keeps the content, and clones made before your fix keep it too. Revoke and replace the key first, then clean history.
Will I be charged for usage before I noticed the leak? Usually yes. Providers bill for requests made with a valid key, and revocation stops future requests only. This is why per-key credit caps (OpenRouter) and spend limits (OpenAI, Anthropic) are worth setting before anything happens.
How often should I run a leak check? A pre-commit hook runs one on every commit, which covers most developers. Beyond that, a monthly history scan plus a monthly skim of provider usage pages is a reasonable rhythm.
None of this takes long. The history scan runs in minutes and the usage pass is a monthly skim. If you are still deciding where keys should live in the first place, the trial shows both storage modes side by side.
Start your free trial → — 7 days, all providers, no credit card required.
The workspace is $2/month or $39 once — AI providers always bill your key directly at their own rates.
See pricingThe Multimodel Journal
Get the latest AI insights, model comparisons, and product updates delivered to your inbox.
Subscribe