← Blog/Explainer

What Happens in the First 5 Minutes After You Leak an API Key

You push a commit with a secret in it. Before you notice, something else already has.

June 3, 2026·Talon Research

< 5 min

Time to first abuse

87

Apps with exposed creds

20+

Key patterns bots scan

The timeline

Industry research puts time-to-first-abuse for high-value keys at single-digit minutes. GitHub themselves report that secrets are detected in commits within seconds of being pushed. The sequence is consistent enough to describe minute by minute.

0:00

You push the commit

A developer pushes code containing an API key to a public repository. Maybe it is hardcoded in a config file. Maybe the AI coding tool inlined it in a React component. Maybe .env got committed because .gitignore was missing an entry. The key is now publicly accessible.

0:01

GitHub detects it

GitHub’s secret scanning runs on every push. It identifies known key patterns and, for supported providers, notifies the issuing service. But not all providers participate in the revocation program, and the notification is not instantaneous revocation. The key is still live.

0:02

Automated bots detect it

Credential harvesting bots continuously monitor the GitHub Events API, which streams every public push in near real-time. These bots run regex matches against commit diffs. They are not sophisticated. They do not need to be. The patterns are trivial.

0:03

The bot validates the key

The bot makes a lightweight API call to the issuing service to confirm the key is live. A Stripe key gets a /v1/charges list request. An AWS key gets an STS GetCallerIdentity call. If the key works, it is flagged for exploitation.

0:05

Exploitation begins

For financial keys (Stripe, payment processors), the bot starts creating charges. For infrastructure keys (AWS, GCP), it spins up compute resources for crypto mining. For database credentials, it dumps the data. The attack is fully automated. No human is involved.

This is not theoretical. In the case of a founder who shipped a Stripe secret key in his AI-coded frontend, attackers charged 175 customers $500 each. $87,500 in fraudulent transactions. $2,500 in non-refundable processing fees. The key was in a public JavaScript bundle, not even a commit. The bots did not need GitHub for that one.

What the bots are looking for

Credential harvesting bots match against known key prefixes and formats. The patterns are well-documented and stable. Here are the ones that matter most.

PatternServiceWhat it grants
sk_live_StripeCreate charges, refunds, read customer payment data
AKIAAWS IAMFull API access scoped to that IAM user’s permissions
eyJhbGciJWT / SupabaseService role can bypass RLS, read/write all tables
AIzaGoogle / FirebaseMaps, Cloud APIs, Firestore depending on key scope
ghp_ / gho_GitHubRepository access, code push, release creation
sk-ant-AnthropicAPI calls billed to your account
sk-OpenAIAPI calls billed to your account
SG.SendGridSend email as your domain
mongodb+srv://MongoDB AtlasDirect database read/write access
postgres://PostgreSQLDirect database read/write access

These are not obscure signatures. Every one of these prefixes is a fixed string that a single regex can match. The bots scanning for them are trivially simple, and they run continuously against every public code source they can reach: GitHub commits, npm packages, PyPI packages, Docker image layers, and public JavaScript bundles served by production websites.

Why deleting the key doesn’t work

The most common first reaction is to delete the secret in the next commit. This does not help. The old commit is still in the git history. Anyone can run git log -p and find the key in the diff where it was added. The bots already have it anyway, because they captured it from the Events API the moment it was pushed.

The same problem applies outside of git. JavaScript bundles are cached by CDNs, indexed by search engines, and archived by the Wayback Machine. A secret that appeared in a production bundle for even a few minutes may exist in caches indefinitely. Package registries (npm, PyPI, Docker Hub) keep old versions available by default. A leaked secret in version 1.0.2 is still downloadable even after you publish 1.0.3.

The only action that stops exploitation is revoking the key at the source. Not deleting the file. Not force-pushing over the commit. Not unpublishing the package. Revoke the key. Everything else is cosmetic.

The right response

If you discover a leaked key, the order of operations matters.

01

Rotate the key immediately

Go to the service’s dashboard and generate a new key. Revoke the old one. This is the only step that stops active exploitation. Do this before anything else.

02

Fix the exposure

Move the secret to an environment variable. Add the file to .gitignore. Move the API call to a server-side route. Whatever caused the leak, close that path so the new key does not end up in the same place.

03

Audit for damage

Check the service’s logs for unauthorized usage during the exposure window. For Stripe, check for unexpected charges or refunds. For AWS, check CloudTrail for unfamiliar API calls. For databases, check for unusual read patterns or data exports.

How to prevent it

The best leaked key is the one that never gets committed. These are the most effective preventive measures, in order of impact.

01

Pre-commit hooks

Tools like git-secrets, TruffleHog, and detect-secrets run on every commit and block pushes that contain known key patterns. This is the single most effective prevention. If a developer or AI tool adds a secret, the commit is rejected before it reaches the remote.

02

Environment variables and .env files

Secrets belong in .env files that are listed in .gitignore. The application reads them at runtime. The key never appears in source code. Make sure .env is in .gitignore before the first commit, not after.

03

Server-side routes for sensitive API calls

Any operation that requires a secret key should run on the server. The frontend calls your API. Your API calls the external service. The secret key never reaches the browser. This is the fundamental architecture that prevents frontend key exposure.

04

Secret managers

For production deployments, use your platform’s secret management: Vercel environment variables, AWS Secrets Manager, GCP Secret Manager, or similar. These inject secrets at runtime without them appearing in code, config files, or Docker images.

The takeaway

The window between leaking a key and losing money is measured in minutes. The bots are faster than you are. They are running right now, scanning every public commit, every published package, every JavaScript bundle they can reach. They do not sleep, they do not get distracted, and they do not need to understand your application. They just need a string that matches a pattern.

In our scanning of over 12,000 recently launched apps, 87 had credentials committed to public GitHub repositories. Connection strings, service role keys, API tokens. Every one of those was exploitable from the moment it was pushed. Most of the developers did not know.

If you are building with AI coding tools, this risk is elevated. The tools do not distinguish between a publishable key and a secret key. They will put whatever gets the code working into whatever file gets it working fastest. The five-minute clock starts the moment that code goes public.

Run a free surface scan

Talon checks your public GitHub repositories for committed secrets, your frontend for exposed API keys, and your server for accessible credential files. Passive, read-only, no account required.

What Happens in the First 5 Minutes After You Leak an API Key | Talon