mabel.ink

The thing I forgot to gitignore wasn't a secret

July 23, 2026

I was careful with secrets in my home lab repo. API keys live in DPAPI-encrypted files outside the repo entirely. The config file holding the scanner URL is gitignored. The Pi-hole backup export is untracked, with a comment explaining that it contains credentials. The Plex settings capture is untracked too, because even with the auth token stripped it still carries account details.

Then I went looking for something else and found a CSV in the repo listing every host on my network with its count of critical and high findings, sorted by risk score.

That file is not a secret. That is exactly why it was there.

What a secrets-focused gitignore looks like

Mine covered the usual:

*.env
*.key
*.pem
credentials.json
secrets/
**/nessus.config.ps1

Every one of those patterns answers the same question: does this file contain a credential? If yes, exclude it. That question is the right one, and the answers were all correct.

It just isn't the only question.

What the scan output actually is

The file I found lists internal hosts with their vulnerability counts by severity and a computed risk score. There is a companion file breaking that down per host, per plugin. A third logs which remediations I applied and when.

Nobody's password is in any of them. What is in them is a prioritized list of which machines on my network are weakest, what specifically is wrong with each one, and, by omission from the remediation log, which findings I have not gotten around to fixing.

If I were attacking that network, this is the file I would want. It is reconnaissance already done, sorted by value, with the work of triage completed for me.

Credentials get you in. This tells you where to go and what to try. Both are worth protecting. Only one of them looks like a secret.

Why it happened structurally

Each project in that repo writes to its own output/ folder. That is a deliberate convention and I like it, because it keeps generated data next to the thing that generated it and out of the source directories.

It also means every script I run drops artifacts into a tracked folder, and the default action after running something is git add .. The repo layout made committing findings the path of least resistance. The gitignore was thinking about files I would deliberately create with secrets in them. The actual risk came from files a script created for me while I was thinking about something else.

The fix is one line:

**/output/

Keep the directories with a .gitkeep if the structure matters. Generated data is not source, and the folders were already named to make that distinction obvious. I just had not carried the distinction into the ignore rules.

The part that is not a one-line fix

The repo is private, so this is contained. But adding an ignore rule stops the next commit. It does nothing about the ones already made.

Git keeps history. If that repo is ever made public, and turning a repo public is a single click that people treat as reversible, every one of those files is recoverable from history even if the working tree is clean. Scrubbing the current state is not scrubbing the repo.

So there are two decisions, not one. Stop committing it, which is easy. And decide whether the history needs rewriting, which is not, and which is a much easier decision to make now than after the repo has been shared.

What I would do differently

I have been sorting files by the question "is this a credential." A better question is "what could someone do with this."

That reframing catches things the first one misses:

None of those are secrets. All of them are useful to someone who does not have your permission.

The irony is not lost on me that I do vulnerability management, and the finding was in my own repo, in the folder holding my vulnerability findings.