Found github-recovery-codes.txt in my vault this weekend, in a folder called Important Docs. The vault is an Obsidian setup that auto-commits every ten minutes and pushes to a private GitHub repo. So the codes for getting back into GitHub were sitting behind the GitHub login.

Think about the day I actually need them - phone gone, authenticator gone, sessions expired. Can’t clone the repo. Can’t open the site. The codes might as well not exist.

And it’s worse than useless, because anyone who ever reads that repo skips my password and my 2FA entirely. That’s what recovery codes do - they’re the bypass for when everything else fails. Sure, the repo’s private. Private is a setting, not a guarantee. The vault also mirrors to a second machine, and for part of those six months the whole folder was inside OneDrive as well. Every copy is a full set of keys.

I get why past me did it. The vault felt like the safest place I had. That was exactly the problem.

Deleting the file fixes nothing

The codes had been in there six months - added end of January, found in August. Two copies, actually: the .txt file, and the same codes pasted into a note beside it, because notes multiply.

Deleting them doesn’t help. Git keeps history, and history is on every clone. I could rewrite history on every machine and still miss a copy somewhere.

Here’s the part worth knowing: recovery codes are the one credential where none of that matters. Regenerate them on GitHub and every old code dies instantly, everywhere, without touching a single file. A leaked password leaves you wondering where it travelled. Leaked recovery codes just need the regenerate button.

So that’s the order I did it in. Regenerate first - now the six months of history holds dead codes. Delete the file and the inline copy second. The history still has them. They open nothing.

The breadcrumb

I replaced the deleted note with a short one saying what used to be here, where it lives now, and why it can’t come back: this vault syncs through the account those codes unlock. Future me will go looking in Important Docs again - past me thought it was the obvious place, so he will too. The breadcrumb is there to break the loop.

The codes live in a password manager now. Should have been there from day one - it’s independent of GitHub, and holding secrets is its whole job. Paper in a drawer also works, honestly.

The question I should have asked

Before a credential goes into any note system: what does this unlock, and does the note system sync through it? If the answer loops back on itself, wrong place. Doesn’t matter how safe it feels.

I’ve written before about generating secrets properly. Turns out that was the easy half. Storing them is where I flunked, quietly, for six months. The fix took ten minutes.