In December 2021, the Log4Shell disclosure (CVE-2021-44228) forced security teams to patch a dependency buried four or five layers deep in build graphs they didn't even know existed. That scramble is the origin story for a newer category of tooling: automated dependency patching. Rather than just flagging a vulnerable package and leaving engineers to figure out the upgrade path, these tools generate the pull request itself — bumping versions, rewriting call sites broken by API changes, and running tests before a human ever looks at the diff. Endor Labs, founded in 2021 by Varun Badhwar, has become one of the most visible vendors pushing this model, layering reachability analysis and AI-assisted code rewrites on top of traditional software composition analysis (SCA). This post breaks down how that patch-generation pipeline actually works, where it tends to fall short, and how Safeguard approaches the same problem with a different set of tradeoffs.
What Is Automated Dependency Patching?
Automated dependency patching is the practice of using tooling — rather than a developer manually editing a manifest file — to identify a vulnerable dependency, select a fixed version, rewrite any code broken by that upgrade, and open a pull request for review. It sits one step beyond traditional SCA, which typically stops at "here is a CVE and here is the fixed version number." A 2023 Sonatype State of the Software Supply Chain report estimated that over 245,000 malicious or vulnerable packages were identified across major registries that year, and the average enterprise Java application pulls in roughly 150 transitive dependencies for every direct one it declares. At that volume, manually triaging and upgrading each affected package is not something most application security teams can do by hand — which is why vendors have started automating the mechanical parts of the fix, not just the detection.
How Does Endor Labs Generate Patches Automatically?
Endor Labs generates patches by combining reachability analysis with an AI code-rewriting step that handles breaking changes across version bumps. The pipeline generally works in three stages. First, its function-level reachability engine determines whether the vulnerable function in a flagged package is actually called, directly or transitively, from the application's own code — Endor Labs has published research claiming that roughly 8-10% of vulnerabilities in a typical dependency tree are reachable at all, meaning the other 90%+ are lower priority by definition. Second, for the reachable subset, the system identifies the nearest non-vulnerable version and diffs the public API surface between the current and target versions. Third, where the upgrade crosses a major version boundary and breaks a call signature (a renamed method, a changed argument order, a removed default export), an LLM-based rewrite step proposes source-level edits to the call sites in the consuming repository, then runs the existing test suite to check the rewrite didn't change behavior. The output is a pull request with the version bump, the rewritten call sites, and a summary of what changed and why.
What Makes a Generated Patch "Safe" to Merge?
A generated patch is considered safe to merge when it passes the same test and build gates a human-authored change would, plus a diff review that confirms the rewrite didn't silently alter behavior. In practice this means the automation needs three things to line up: a test suite with meaningful coverage of the affected code paths, a CI pipeline that actually blocks merges on failure rather than just reporting status, and a human reviewer who reads the generated diff rather than rubber-stamping it because a bot produced it. Take a Lodash prototype-pollution fix (CVE-2021-23337, disclosed February 2021) as an example: bumping past the patched version is a one-line change with no API break, so an automated patch there is genuinely low-risk. Compare that to a major-version jump on a framework like Spring or a testing library like Jest, where dozens of call sites might need rewriting — the blast radius of an incorrect automated rewrite is much larger, and "the tests still pass" is a necessary but not sufficient signal, since most internal test suites don't cover every edge case an API change can touch.
Where Does Automated Patching Break Down?
Automated patching tends to break down at major-version boundaries, in dynamically typed languages, and in monorepos with shared internal packages that multiple services depend on differently. Static analysis and LLM-based rewrites work well against well-typed, well-documented APIs — Java and TypeScript codebases with clear signatures give a rewrite engine something concrete to diff against. Python and JavaScript code that relies on duck typing, dynamic imports, or metaprogramming gives it far less to work with, and reachability analysis itself can under- or over-count call paths in these languages because there's no compiler enforcing the contract. There's also a coordination problem: if package A is upgraded in one service but a shared internal library still assumes the old API, an automated patch that only touches the immediate repository can pass its local tests while breaking a downstream consumer it never saw. And because these systems still depend on an upstream fixed version existing, they don't help with the share of disclosed vulnerabilities that, per historical NVD backlog data, take 60 days or more to receive an official patched release — automation can't upgrade you to a version that doesn't exist yet.
How Does Automated Patching Fit Into a Vulnerability Management Program?
Automated patching fits into a vulnerability management program as the last-mile execution step, not a replacement for prioritization. The sequence that actually reduces risk still runs: inventory (know every dependency, including transitive ones, via an SBOM), prioritize (reachability, exploit maturity, EPSS score, and asset criticality — not just CVSS base score), and only then remediate. Skipping straight to "auto-patch everything with a CVE" produces the same alert fatigue SCA tools were supposed to fix, just with more pull requests instead of more tickets — teams that auto-generate patches for every CVE regardless of exploitability commonly report needing to close or ignore the majority of the resulting PRs, because a patch for an unreachable, low-severity finding still consumes reviewer time to dismiss. The tools that get adopted long-term are the ones that gate patch generation behind a prioritization step, so engineers only see automated PRs for the vulnerabilities that were worth fixing in the first place.
How Safeguard Helps
Safeguard treats automated remediation as the output of a prioritization pipeline, not a standalone feature bolted onto a CVE feed. Every dependency in your SBOM is scored using reachability analysis, exploit maturity signals, and deployment context — is this package in a service that's internet-facing, does it handle authentication, is the vulnerable function actually invoked — before it's ever queued for a patch. That scoring runs continuously, not just at scan time, so a dependency that was low-priority last month gets re-flagged the moment a public exploit or a change in reachability shifts its risk.
When a fix is warranted, Safeguard generates the remediation pull request with a full audit trail: the version diff, the CVE and advisory references, the reachability evidence that justified prioritizing it, and test-run results attached directly to the PR — the same artifact trail SOC 2 auditors expect to see for change management evidence. For upgrades that cross breaking-change boundaries, Safeguard flags the specific call sites affected rather than silently rewriting them, so reviewers can decide how much automation to trust on a case-by-case basis instead of accepting an all-or-nothing black box. Tenant-scoped policies let platform teams set different automation thresholds per repository or business unit — full auto-merge for low-risk patch bumps in low-criticality services, mandatory human review for anything touching a payment or auth path — so the speed of automated dependency patching doesn't come at the cost of the audit rigor a supply chain security program actually needs.
The result is fewer, better-targeted pull requests: engineers see patches for the dependencies that were actually reachable and exploitable, with enough context to review a generated diff in minutes instead of re-deriving the reasoning from scratch. That's the difference between automated dependency patching as a volume play and automated dependency patching as a risk-reduction tool — Safeguard is built for the latter.