Find the leaked secrets and rotate them
Continues from the last build: Injection and access-control holes are closed and regression-tested.
Two rungs ago you locked down who can touch which account. Last rung you killed the SQL injection in the transfer search endpoint.
What you'll build
The database password and the leaked API token are rotated, so the old values recovered from history are worthless. Gitleaks has scanned the full commit history, the findings are documented with commit SHA and rule ID, and the exposed strings are removed from history with a written caveat that any existing clone or fork still has them, which is exactly why rotation happened first. A pre-commit hook and a CI gate both run gitleaks on every future commit and pull request, so a new secret gets caught before it is pushed, not after. All app configuration comes from environment variables sourced from the platform at deploy time, never from the repo, with a .env.example documenting the contract.
See how we teach, before you sign up
You don't just get code dumped on you. Every starter file and every solution is explained line-by-line, in plain English. Here's one real file from this project:
# committed by mistake three rungs ago during a demo DATABASE_URL=postgresql://ledgerline_app:CorrectHorse1!@db:5432/ledgerline LEDGERLINE_API_TOKEN=sk_live_4f8a9c2e7b1d4a6f9c0e2b7a PORT=3000
Reading this file
DATABASE_URL=postgresql://ledgerline_app:CorrectHorse1!@db:5432/ledgerlinea real password embedded directly in a tracked file, this is the exposure milestone 1 finds and milestone 2 rotatesLEDGERLINE_API_TOKEN=sk_live_4f8a9c2e7b1d4a6f9c0e2b7aa live-looking token checked in from a demo, the second leak this rung addressesPORT=3000non-secret configuration; it is fine for this one to live in a file, the problem is only the two lines above it
This file should never have been committed. It is tracked in git and its values are readable in history even after later commits delete the lines.
That's 1 of 6 explained code blocks in this single project.
The build, milestone by milestone
- 1
Scan the full history with Gitleaks
5 guided stepsMost people scan HEAD, see nothing, and conclude the repo is clean. The password was deleted from the file three commits ago, so a working-tree scan misses it completely. History is the actual attack surface: anyone who ever cloned the repo, or anyone who can still reach it through a fork, a CI cache, or a backup, can run git show against the old commit and read the plaintext value.
- 2
Rotate first, always
5 guided stepsPurging git history does nothing to the secret itself, it only makes the string harder to find going forward. Anyone who already cloned the repo, forked it, or has it in a CI log still has the old password and token. The only thing that neutralizes a leaked credential is making it stop working. This is the single most-skipped step in real incident response: teams rush to scrub history and skip rotation, leaving a fully functional stolen credential in the wild.
- 3
Purge history and stop the next leak
6 guided stepsHistory rewriting is cleanup, not protection, the credential was already rotated in the previous milestone. Purging matters for hygiene, for compliance evidence, and so the string does not keep tripping future gitleaks scans, but it cannot be your only defense: every existing clone, fork, or CI artifact keeps the old history until they re-clone. The real long-term fix is making it structurally hard to commit a secret again, which is what the pre-commit hook and CI gate do.
- 4
Move secrets to the right place
5 guided stepsThe leak happened because there was no clear line between 'this is a value the repo documents the shape of' and 'this is a value that must only ever live in the platform's secret store'. Without that line, the next developer under deadline pressure will do exactly what the last one did: paste a real value into .env to get unblocked, and commit it by habit.
- 5
Prove it end to end
5 guided stepsA green scan is evidence of absence of the specific patterns gitleaks knows to look for, it is not proof the repo is secure. State that honestly. What you can prove is narrower and just as important: the specific leak that happened is gone, the specific class of mistake (a real secret landing in a commit) is now caught automatically at two independent layers (pre-commit and CI), and the rotation makes the historical exposure moot regardless of what a scanner does or does not catch later.
What's inside when you start
You'll walk away with
This is portfolio-grade. Build it free.
Sign up to unlock every milestone step-by-step, the code skeletons, full reference solutions, and checkable tasks, with your progress saved as you build.
Start building