Know what is broken, before someone else does.
Keywords
CVE, GitHub Advisory Database, OSV, CISA KEV, gitleaks, endoflife.date, RDAP, security headers, Dependabot, GitHub Actions
Why
I have a handful of side projects: Mate, the app I plan my days in, Haftam, a weekly plan for getting your credit back in order, Oturdum, tenant reviews on a map, Okur, a reading app, turken.xyz, my personal site, and this blog. Most of them are written with Claude, and most of them get no attention for weeks.
Dependencies don’t wait for me. A package that was fine when I added it gets a CVE three months later, and nothing tells me. Old commits are worse: a password I pasted into a config file years ago is still there in the history, long after the file is gone. And frameworks quietly run out of support, certificates and domains expire, licences change.
So once a week, every project gets checked, and the result lands in one place I already look at.
Why Wednesday
Microsoft ships .NET security fixes on Patch Tuesday, the second Tuesday of the month. Most of my projects are .NET, so a Wednesday scan sees those advisories the next day instead of three days later. It also leaves the rest of the week to fix and deploy, instead of a Friday report that means either shipping before the weekend or leaving it open over it.
It runs at 06:17, not 06:00. GitHub delays scheduled runs at the top of the hour, when everyone’s cron fires.
Setup
1- ๐
Wednesday morning, GitHub Actions starts the scan in every repo
2- ๐ฆ Dependencies, checked against known CVEs
3- ๐ Secrets, the whole git history
4- โณ End of life, frameworks running out of support
5- ๐ Live sites, certificates, domains and headers
6- โ๏ธ Licences, copyleft or not what my ledger says
7- ๐ฅ Ranked, actively exploited first
8- ๐ One issue per repo, updated every week
One shared action: the scan lives in its own small repo as a composite action. Each project only has a 20-line workflow that calls it, with the sites it serves, so a fix to the scan reaches every project at once.
Dependencies: no new scanner, just the tools that already read my lockfiles: dotnet list package --vulnerable for NuGet, npm audit for npm, pip-audit for Python. Each advisory is then looked up on OSV for its CVE IDs and the smallest version that fixes it.
Ranking: anything on CISA’s Known Exploited Vulnerabilities list goes to the top. Then severity, and runtime packages before test-only ones. A dev dependency in the test project should not shout as loud as the one in the API.
Secrets: gitleaks runs over the full history, not just the latest commit. A known false positive goes into .gitleaksignore with a comment saying why.
End of life: the .NET target frameworks, the Angular version and the Node engine are checked against endoflife.date. Anything already out of support, or ending within 90 days, shows up with the version to move to. An unsupported framework gets no new advisories, so the CVE check goes quiet exactly when it matters.
Live sites: each site’s certificate (21 days ahead) and domain (30 days, from RDAP), whether http:// redirects to https://, and the usual security headers: HSTS, CSP, X-Content-Type-Options, Referrer-Policy, X-Frame-Options.
Licences: every direct dependency’s licence, read from the lockfile or the package itself. A copyleft licence gets flagged, and so does a licence that is not what my THIRD_PARTY.md ledger says.
The issue: one per repo, labelled security-scan. Every run rewrites it, marks what is new and what was fixed since last week, and comments only when something new appears. A clean run closes it. Findings never fail the run, only a part that could not be scanned does. A finding I accept on purpose goes into .security-scan-ignore, with a comment saying why.
On top of that, Dependabot is on everywhere, so the fixes arrive as pull requests.
First run
The first run was worth it. Haftam had a pile of npm advisories in its front end tooling. Okur’s solution file only built on Windows, because a folder name differed in case. Mate came back clean, apart from two test values that only look like keys. And the older projects still had passwords and keys sitting in the history of config files deleted long ago.
The extra checks found more. Okur still targets .NET 8, a week before its support ends. Haftam, Oturdum and this blog are missing some security headers. And a package Mate uses had moved from MIT to Apache 2.0 in a major version, while my ledger still said MIT.
None of it was visible from the code as it is today.
Prompts
Plan a weekly security scan for all my repos, based on a CVE source. Compare running it locally, as a cloud agent or in GitHub Actions, and recommend one, and the best day of the week for it.
Build it as one shared composite action. Use the platform tools for each ecosystem, enrich advisories from OSV, flag CISA KEV, scan secrets with gitleaks, and keep one issue per repo that shows what is new and what was fixed. Test the report logic with
node:test.
Add end of life checks from endoflife.date, live site checks (certificate and domain expiry, the https redirect, security headers) and a licence check against
THIRD_PARTY.md. Let a finding be accepted through an ignore file.
Add the workflow and a Dependabot config to every repo, one PR each, and turn on Dependabot alerts.
Pros
1- โ
Free, a few Actions minutes a week, no extra service
2- โ
One place per project, an issue I already get notified about
3- โ
Only news is noise, a comment appears only when something is new
4- โ
Actively exploited first, not just a long list sorted by score
5- โ
Old secrets surface, the history is scanned, not just today's code
6- โ
Slow problems surface, end of life and expiry dates show up months ahead
7- โ
One fix, every repo, the scan lives in one place
Cons
1- โ Only known vulnerabilities, my own bugs are not in any database
2- โ Secret scanning is noisy, test tokens and library code show up and need ignoring
3- โ An ignored secret is still valid, rotating or deleting is still my job
4- โ Weekly, a critical CVE on Thursday waits six days for the scan (Dependabot alerts help here)
5- โ Unpinned Python ranges are checked as they resolve today, not as they were deployed
6- โ Headers are opinionated, a missing CSP is a finding even where I chose not to have one
Closing
It is not a security program, just a weekly habit that runs without me. But it changed what I know about my own projects. The old ones especially, the ones I thought were finished.
A project I stopped looking at is still running somewhere, with its dependencies, its certificates and its history.
That’s the part worth checking.