1. The Problem
Our team manages over 30 internal repositories / web apps, APIs, automation scripts, you name it. Each one has its own set of dependencies, and every week, new security vulnerabilities are inevitably discovered.
We have scanners that do a great job of detecting these issues and filing them as GitHub Issues, complete with severity levels and SLA deadlines. But the actual remediation (opening the repo, finding the right manifest file, bumping the version, running the tests, and opening a PR) was entirely manual.
At any given time, we were staring at 100+ open findings across all our repos, some already bleeding past their SLA deadlines. It had become a weekly time sink that pulled engineers away from actually building things.
We needed a way to go from “vulnerability detected” to “PR ready for review” with zero human intervention.
2. Enter “vuln-fixer”
To solve this, we built a Python command-line tool that automates the entire remediation pipeline. You point it at your repositories, and it does the heavy lifting:
- Fetches all open vulnerability findings for your team.
- Prioritizes them (missed SLAs first, then critical severity, etc.).
- Fixes the vulnerable dependencies automatically.
- Opens Pull Requests with a clear, human-readable summary of what changed and why.
3. The AI-Powered Fix Engine
The most interesting part of this tool is how it applies the fixes.
We started with the obvious approach: regex-based fixers. They parse package.json, requirements.txt, or go.mod and surgically update a version string. This works perfectly for simple cases like “bump package X from 1.2.3 to 1.2.4.”
But real-world vulnerabilities are messy. Sometimes the fix involves updating a Docker base image. Sometimes the vulnerable package is hiding in a weird custom script. Sometimes multiple files need coordinated changes. The regex approach quickly became a nightmare to maintain.
So, we added an AI layer, powered by GitHub Models (using GPT-4.1). Here is how we do it without it hallucinating all over our codebase:
- The tool reads the manifest files and
Dockerfiles. - It sends them to the model along with structured vulnerability data (package name, current version, target version, CVE).
- The secret sauce: We don’t ask for free-form code. We enforce a strict JSON schema where the model must return an array of
{file_path, search, replace}objects. - The tool applies these exact string replacements and then regenerates the lockfiles (
npm install,go mod tidy, etc.).
By forcing the “search” string to be an exact substring of the current file, the response becomes deterministic. No parsing ambiguity, no guessing where changes should go. We also batch findings to save tokens and deliberately exclude lockfiles from the prompt to keep the context hyper-focused.
(Note: The regex-based fixers are still there as a fallback via a --no-ai flag for CI environments that require 100% deterministic, offline behavior).
4. Smart Prioritization
Not all vulnerabilities are created equal. The tool sorts the work before it starts:
- Tier 1: Missed SLA repos (already overdue).
- Tier 2: Near SLA repos (approaching the deadline).
- Within each tier, Critical and High severity findings jump to the front of the line.
If the tool gets interrupted, or if you only have time to review a few PRs, you know the most impactful work got done first. Findings that require actual logic changes (like code-scanning alerts) are flagged in the PR so engineers know where human judgment is actually needed.
5. Running on Autopilot
Every PR the tool creates includes a clean table of dependency changes, the SLA status, a list of unfixable findings, and automatically requests review from the team. Most of these PRs are instant approvals.
Beyond the CLI, we now run this as a scheduled cronjob. It uses the exact same logic but reads from environment variables. It keeps our vulnerability count flat while we sleep.
6. Conclusion
Before this tool, vulnerability remediation was a multi-hour weekly ritual. Now, the routine dependency bumps are handled by a script, and engineers only step in for the edge cases.
The combination of structured vulnerability data and an AI model constrained to simple text patching is incredibly powerful. The AI doesn’t need to understand your entire architecture; it just needs to know what files to look at and what versions to change. That narrow scope is exactly what makes it reliable enough to trust in an automated pipeline.
If your team is drowning in Dependabot alerts, stop doing robot work. Automate the patch, constrain the AI, and get your Fridays back.