cd ..

I Built a Tool Nobody Asked For

|3 min read|
devtoolsgithub-actionsopen-source

Last August, I noticed something annoying about GitHub Actions.

Secrets can silently resolve to empty strings. Not null. Not an error. Just an empty string. Your workflow keeps running, and then something downstream fails — "authentication failed", "invalid API key", a 401 from some server. You spend an hour debugging auth when the real problem was that the secret wasn't there in the first place.

This happens more often than you'd think. Fork PRs, dependabot runs, misspelled secret names, wrong environment scope. GitHub does this by design. It's a security choice. But the developer experience is terrible because the error never says "hey, your secret was empty."

The landing page that nobody visited

I thought this could be a product. Made a landing page. Reached out to people on GitHub, emails, Reddit. Tried to validate if this was a real problem that people would pay for.

Nothing. No genuine interest. A few polite replies. Mostly silence.

So I dropped it. Moved on to other things.

20 signups from nowhere

A few months later — last week actually — I randomly opened the signup sheet for that dead landing page.

20 signups.

Most of them were probably bots. The emails looked like uhekapuyok436@gmail.com and owagesas170@gmail.com. Classic spam patterns.

But still. 20 entries on a page I thought nobody visited.

I don't know why, but that was enough. I decided to just build the thing. Not as a SaaS. Not as a paid product. Just a simple open source CLI that solves the problem.

What I built

ghostsecret — a CLI that scans your GitHub Actions workflow files and finds secrets that will silently disappear.

bash
npx ghostsecret

It checks for:

  • Secrets used in workflows triggered by pull_request — these are empty on fork PRs
  • The dangerous pull_request_target + checkout pattern that can leak secrets
  • Misspelled secret names, with fuzzy "did you mean?" suggestions
  • Secrets defined in your repo but never used in any workflow
  • Secrets used without empty-string guards

The whole thing took about a day to build. TypeScript, no fancy architecture. Parse the YAML, regex out the secret references, run a few rules, print the results.

What I learned

Validation is weird. I did the "right" thing — made a landing page, reached out, tried to gauge interest before building. Got nothing. Built it anyway because of 20 bot signups on a forgotten page.

Sometimes you just have to ship the thing and see what happens. The feedback you get from a working tool is different from the feedback you get from a landing page. People can't tell you if they want something that doesn't exist yet. But they can tell you if something you made is useful.

ghostsecret is v0.1. Rough around the edges. I'll only build v0.2 if people actually use v0.1.

If you use GitHub Actions, give it a try. If it catches something, let me know.

bash
npx ghostsecret