How to check a repo for secrets before you make it public

2026-07-31 · Yusuf Gadelrab

No affiliate links on this page Nothing here is monetized. Every tool named is either free, open source, or something I built and give away. If that changes I will put a disclosure at the top, the way I do on the pages that do carry affiliate links.

Deleting an API key from a file does not delete it from your repository. It is still in the object store, it is still reachable, and the moment you flip that repo to public it is indexed by people whose entire job is finding it. This is the single most common way a student project leaks a credential, and it takes about ten minutes to prevent.

I wrote a security scanner to automate this for myself, so this checklist is what my own tool actually does, in order, explained so you can do it by hand if you would rather.

The five-minute version

  1. Search the working tree for secrets.
  2. Search the git history for secrets, which is a different search.
  3. Check what is actually tracked, not what you think is ignored.
  4. Check dependencies for known vulnerabilities.
  5. Check the deployed thing, because half of real exposure is config, not code.

Most people do step one, feel relieved, and skip the other four. Step two is the one that bites.

1. The working tree

Start with the obvious pass, but widen the net past the patterns you already know:

2. The history, which is the one that gets people

This is the step that matters. Your commit that removed the key added a new commit. The old blob containing the key is still in the repository and anyone who clones it gets it.

To see for yourself, this walks every blob that has ever existed rather than only the current checkout:

git rev-list --objects --all

Piping that through a pattern search across the blob contents is what history scanning actually is. Doing it by hand on a repo with any real history is slow, which is exactly why I automated it.

And the part people do not want to hear: if a real credential was ever committed, rotate it. Do not rewrite history and call it handled. Rewriting is worth doing, but the moment a secret hits a remote you must assume it is compromised, because forks, caches, CI logs, and mirrors do not care about your rebase. Rotate first, clean second.

3. What is actually tracked

A .gitignore entry does nothing for a file that was already tracked before you added the rule. Git keeps tracking it. This surprises people constantly.

git ls-files shows you the truth. Read it. Look specifically for anything ending in .env, .pem, .key, .p12, .sqlite, .db, or .pfx, plus anything in a folder called config, secrets, or credentials.

Also check whether your repo should be public at all. If it contains anything from an employer, an internal schema, or a customer's data, the answer is no, and no amount of scanning changes that.

4. Dependencies

Your lockfile is a list of other people's code that runs with your permissions. You can check it against the OSV database, which is free, public, and needs no account. Query it with your package name and version and it tells you the known vulnerabilities.

Two things worth flagging while you are in there. First, transitive dependencies are where the surprises live, so check the resolved lockfile, not your manifest. Second, check licenses at the same time. A GPL dependency deep in a product you intend to sell is a business problem wearing a technical costume, and it is much cheaper to find now.

5. The deployed thing

Code scanning cannot see your headers. Once the project is live, check the boring config layer:

The category most checklists miss: LLM integration

If your project calls a model, you have surface that did not exist in older checklists and that most scanners still say nothing about:

Automating the whole thing

I built DIRA because every scanner I found wanted me to install a large dependency tree in order to go looking for supply chain risk, which struck me as funny in a way that is not funny. It has zero dependencies, it is MIT licensed, it is free, and it runs everything above: secrets, git history, dependency CVEs through OSV, config and infrastructure-as-code rules including the LLM ones, license risk, and live TLS and header checks.

It outputs SARIF so it drops into GitHub code scanning, and it has a diff mode so you can gate pull requests on it. There is more on how and why in the write-up.

If you run it on something real and it misses something it should have caught, that is the feedback I want most.

Before you click "make public"

Scan the tree. Scan the history separately. Read git ls-files with your own eyes. Rotate anything that was ever committed, even if you removed it. Check the lockfile against OSV. Then check the deployed config, because that is where the other half of real exposure lives.

Built by one CS student in San Jose.

Free tools, three installable offline apps, and two SIGCSE 2026 papers. See the work or read the facts. Open to Summer 2027 software engineering, AI/ML, and quant internships.