Security & repair
Finding what's
already broken.
A credential doesn't have to be in your code to be leaked. It only has to have been there once. This is a real audit: the method, what it found, and what fixed it, with every identifying detail removed.
Open the interactive audit
run a scan against a mock codebase, fully workingThe method
Scanning the current checkout is the part everyone does, and it's the part that finds nothing. Git keeps deleted files forever. A key committed in March and removed in April is still in history in December, fully readable by anyone who can clone.
- Full clones, every branch, not just the default branch, not a shallow fetch.
- Every commit that ever existed, walked from the root, rather than only the current tree.
- Deleted-file recovery, specifically hunting files that were removed, which is where secrets hide once someone "cleans up."
- Pattern classes, not just known prefixes, API keys, bearer tokens, JWTs, private keys, connection strings with inline credentials.
- Endpoint and personal-data sweeps, hardcoded webhook URLs, real names, personal email addresses in seed and mock data.
What it found
Admin-scope token, recoverable from history Critical
An automation platform's API key, admin scope, no expiry, hardcoded in two files that had both been deleted months earlier. The working tree was completely clean and read the value from an environment variable, exactly as it should. The key was still trivially recoverable from history by anyone with clone access, and still valid.
Personal data in a public repository Critical
Mock and seed data containing real family names and personal email addresses, in a repository that was public. Present across the entire commit history, so deleting the current file would have changed nothing.
Hardcoded webhook endpoints Medium
Live automation endpoints written directly into client-side source across seven projects. Not credentials, but a published map of the backend, and in a public repo, an open invitation to send them traffic.
The good news, which matters: no payment keys, no cloud provider credentials, no service-role database keys, no committed environment files anywhere in any tree or any history. Current code handled secrets correctly throughout. The exposure was entirely historical: which is exactly the part that normally goes unchecked.
The fix
Before
const API_KEY =
"eyJhbGciOiJIUzI1NiIs…";
fetch(`https://hooks.internal
.example/webhook/a1b2c3`, {
headers: { key: API_KEY }
});
After
const API_KEY =
process.env.API_KEY;
fetch(`${process.env.HOOK_BASE}
/webhook/${id}`, {
headers: { key: API_KEY }
});
But moving it to an env var doesn't fix a leak. That's the part people get wrong. Once a credential has been public, it is burned, someone may already have it, and no amount of history rewriting can un-copy a clone. The real sequence is:
- Rotate first. Before anything else, invalidate the exposed credential. Everything else is cosmetic until this is done.
- Then move to environment configuration, so the new value never enters version control.
- Then make the repository private if it holds personal data, and treat anything that was public as already copied.
- Then add pre-commit scanning, so the next one is caught before it's ever committed rather than a year later.
Repair work
Things someone else built and left.
The same instinct applies to broken systems generally: find what's actually wrong before touching anything. Automations that fail silently, a workflow that worked until an API changed under it, a spreadsheet holding a business together that nobody dares edit.
One honest boundary: I need real access to fix things properly, the code and the environment it runs in. Partial access means guessing, and guessing means I own the blame for the next thing that breaks. If I can't see it, I'll tell you rather than charge you to speculate.
Want to know what's in your history?
Most teams have never looked. It's usually clean: and when it isn't, you want to find out before somebody else does. I'll tell you what's exposed, what to rotate first, and what genuinely doesn't matter.