Case study // Tool
Audit scanner: a nightly run over my own repositories
Every night a container checks my own repositories for CVEs, floating pins and stale images, and opens the fix pull requests itself.

01Context
The update obligation lived in my own rulebook, but the execution stayed manual: check every container tag, watch every range, read every advisory. It only held as long as I remembered to do it.
So a batch job took it over. Overnight, unattended, with a Telegram message in the morning.
02How it was built
The inventory comes from the GitHub API: every repository of the account, public and private, forks excluded, archived ones never counted. Each repo is pulled as a tarball so the scan needs no cache and no working copy.
Trivy runs twice: `trivy fs` against the dependencies, `trivy image` against every FROM reference in Dockerfiles and every image reference in Compose. Findings are matched against the GitHub advisory database, including a semver comparison and first_patched_version - without a patched version there is no fix PR, only a note.
Renovate runs as analysis only (--dry-run=lookup), because it judges floating or outdated tags differently than a CVE scan. Found ranges are pinned to exact versions, image tags to version plus digest.
Fix PRs are created over the REST API without a git clone, on separate branches per kind, and persistent state prevents duplicates across days. Everything goes through the same gates as any other change: lint, typecheck, tests, build.
03What I learned
A failure before the report is a silent outage: a root-owned digests.json made the run abort with EACCES for two nights, with no report and no message - from the outside it looked like 'nothing found'. Since then there is a daily receipt and an exit trap that reports the abort.