Secrets

A leaked API key scanner finds the one defect that costs money today.

Every other finding in a code review can wait a sprint. A credential in source is a live incident with a clock on it, and generated code puts them in places nobody thinks to look.

Why assistant-written code leaks keys

A model asked to make an example work will produce a working example, and a working example usually needs a credential. It writes one in the obvious place because the prompt asked for runnable code rather than deployable code.

The second route is subtler: a developer pastes a failing snippet including the real key, asks why the connection fails, and pastes the answer back. The secret enters the file as part of the fix, disguised as the thing that was already there.

A third route is documentation. Example blocks, README quickstarts and test fixtures are still source, they still get committed, and they are read by people who copy them.

What the scanner matches

The rules look for two things: provider-shaped strings and assignment patterns that name a secret.

  • Cloud, payment, messaging, source-hosting and database keys that carry a recognisable prefix or structure for that provider.
  • Private key blocks, which are unmistakable and among the most damaging to lose.
  • Connection strings with an embedded password.
  • Assignments where the variable name says password, secret, token or apiKey and the value is a string literal.

Triage: real, test, placeholder

Not every match is a live credential, and treating them all as emergencies is how scanners get muted. Sort each finding into one of three buckets.

Real means a credential that grants access to something. Rotate first. Test means a key from a sandbox or a demo tenant; still rotate if it is not obviously scoped, but the urgency is lower. Placeholder means a pattern-matched string such as an example value or a fixture, which is a legitimate exemption to record rather than a fix.

The classification takes seconds per finding and is worth doing properly, because a scanner that cries wolf on fixtures stops being read on the day it is right.

Rotation before clean-up, always

The instinct is to edit the file. That does nothing about the exposure, and it delays the only action that reduces it.

The order is: revoke or rotate the credential at the provider, review the provider's access logs for the exposure window, then clean the code, then clean the history if the repository is not private. Deleting the line while the key remains valid is a tidy way to keep an incident open.

Treat the finding as the start of an incident review, not the end of a task. The label the pattern matched tells you which provider console to open first.

What a single-file scanner cannot see

It sees the text you give it. It cannot tell you whether the key is valid, which permissions it carries, whether it was already in a previous commit, or whether it has been pushed to a fork or a screenshot.

So use secrets scanning in the repository as well. The file-level check is for the moment before the commit, when the fix is still free; the repository scan is for everything that already happened.

Both are needed because they operate at different times. The console catches it while the code is still in someone's editor; history scanning catches what slipped past.

Making the next one less likely

Three habits remove most of the volume. Ask for configuration rather than working examples. Keep secrets in environment variables and reference them, never paste a real value into a prompt. And when a snippet fails, reproduce it with a dummy value rather than the real one.

Add a pre-commit hook if the team will tolerate one, and make the console the first thing that happens to any pasted code. A three-second check before the commit is cheaper than a rotation, a history rewrite and a note to the security team.

Finally, write down what to do when a key is found. A one-page runbook that starts with revoke and ends with a history note turns a panicked afternoon into a fifteen-minute procedure.

What this covers

  • Provider patterns

    Cloud, payment, messaging, hosting and database keys with recognisable shapes.

  • Private key blocks

    PEM headers and other unmistakable credential containers.

  • Connection strings

    Database URLs with an embedded password.

  • Named assignments

    Literals assigned to variables called password, secret, token or apiKey.

  • Test fixtures recognised

    Recorded exemptions rather than repeated false alarms.

Questions this page usually raises

Does the scanner tell me whether a key is active?
No. It matches patterns in text and has no way to test a credential. Assume any plausible match is live until the provider console says otherwise.
Should I paste real keys into the checker?
You can, because the check runs in your browser, but you should rotate anything real regardless. The safer habit is to rotate, then check the cleaned file.
Does deleting the line fix the leak?
No. If it was committed or shared, the credential survives in history and in any clone. Revoke and rotate first, then clean up.
Will it find every kind of secret?
No scanner does. It covers common provider formats and named assignments; tickets, cookies and obfuscated values can still slip through, which is why repository-level scanning matters too.
Can it scan a whole repository?
The console checks pasted files individually. For history and cross-file coverage, pair it with a secrets scanner in your pipeline.

Leaked API key scanner

Run the checks, then decide who has to sign it.

The automated pass is free, needs no account and uploads nothing. Escalate to a named reviewer only where being wrong is expensive.