Why patching is hard, and why "just upgrade" isn't always the answer
Every security team has been there. A CVE drops for a library your application depends on. The fix is in version 4.0. You're on version 2.3. The upgrade path requires API changes, a rewrite of internal components, and three sprints of engineering time. Meanwhile, the vulnerability is active.
The conventional advice to upgrade to the patched version assumes upgrades are free. They're not. In production Java ecosystems especially, a major version bump can break binary compatibility, violate transitive dependency contracts, and send ripple effects through a monorepo. Security teams and developers end up in a standoff: accept the risk and stay put, or pay the upgrade tax and accept the disruption.
This is the problem Endor Patches were designed to solve.
But there's a second problem that rarely gets talked about: trust. When you apply a third-party patch to a production dependency, how do you know what's in it? How do you know the fix actually works? How do you know nothing else was changed?
To that end, we've published two complete examples of Endor Patches in the endor-patches repository, giving anyone the ability to inspect how a patch was created, review every code change, reproduce the build, and verify the published artifact themselves. These examples are intended to make our patching process transparent, not just describe it.
What are Endor Patches?
Endor Patches are security backports: vulnerability fixes surgically applied to older library versions that can't be upgraded without breaking compatibility. Three principles govern every .patch:
- Minimal: Only the changes necessary to neutralize the CVE. No non-security bug fixes, no refactoring, no opportunistic cleanup.
- Compatible: The patched JAR is a drop-in replacement. Same API, same behavior, same build toolchain. Your pom.xml change is one line.
- Verified: The full upstream test suite runs against the patched source. A patch is only published when every test passes.
Building a patch sounds simple in easy cases: cherry-pick the upstream fix commit onto the older branch. But it gets hard. When a vulnerability is fixed in a newer version through significant code restructuring, the relevant classes may not exist at all in the older version. Or the fix in the upstream project was to remove the vulnerable feature entirely, a breaking change that can't be backported. In those cases, Endor Labs authors the fix from scratch, and that's precisely where transparency matters most.
If you're looking for a deeper explanation of how Endor Patches are engineered and tested, Henrik Plate's article, How Endor Patches Are Built and Tested, walks through the underlying patching workflow in detail. This repository builds on that foundation by making the process independently verifiable.
Why transparency and reproducibility aren't optional
When you consume a patched artifact from any source, you're trusting a claim: "this JAR does what we say." That claim is unverifiable unless you can read the diff, inspect the build, and reproduce the output yourself.
This isn't hypothetical paranoia. The software supply chain attacks of recent years have shown that build artifacts are a high-value target. Patching infrastructure is especially sensitive, it sits between a known vulnerability and production systems, making it an attractive injection point.
For every patch, Endor Labs publishes:
- Security attestation: The exact diffs applied to source, each mapped to a CVE. Every commit is labeled: COMMIT_TYPE_UPSTREAM (backported from the original maintainer's commit, verifiable by SHA on GitHub) or COMMIT_TYPE_MANUAL (written by Endor Labs, readable in full in patch_files).
- Build attestation: Full compiler output from the hermetic Docker build: the pinned image tag, every Maven/Gradle step, dependency resolution, and output artifact.
- Test attestation: The complete upstream test suite output, not a summary. Every test that ran, every result, so nothing can be quietly excluded.
- Deploy attestation: The exact artifact path and registry URL where the JAR was published.
- Reproducible build source tarball: Everything needed to rebuild the patched artifact from scratch: upstream source pinned to a specific commit SHA, the patches applied, Bazel workspace and build configuration, and step-by-step instructions. Build it yourself with Docker and Bazel, and compare the output checksum against the published artifact.
Builds are hermetic. The same source produces the same artifact, every time. That's what reproducible means in practice: not a marketing claim, but a verifiable guarantee.
What's in the repository?
The repository contains two complete Endor Patch examples covering real-world, high-severity vulnerabilities:
These are representative examples of how Endor Patches are produced, and each contains everything needed to inspect the patch from start to finish.
Here's what you can do with the endor-patches repository (https://github.com/endorlabs/endor-patches):
Audit a patch independently. Open security_attestation.json for a patch. Find entries with "fix_type": "FIX_TYPE_VULN". Read patch_files — those are the security diffs. For any COMMIT_TYPE_UPSTREAM commit, look up the SHA on GitHub and confirm the diff matches exactly. For COMMIT_TYPE_MANUAL commits, read what Endor Labs actually changed and judge for yourself whether it's appropriate. For woodstox-core, all commits are pure upstream backports. For jgit, the manual commits are build system changes only, with no security-sensitive code touched.
Reproduce the build from scratch. Each patch directory includes a source tarball with everything needed: a Bazel WORKSPACE file that fetches upstream source at a pinned commit SHA, build patches, vulnerability patches, and Bazel configuration. Extract, follow the included README.md, and produce the artifact yourself. What comes out should match the SHA256 in SHA256SUM.txt.
Install and use the patched JARs directly. The artifacts are in patches//artifacts/. Verify the SHA256, install to your local Maven repository with mvn install:install-file, and declare the dependency with the -endor-YYYY-MM-DD version string. Works for both direct dependencies and transitive override via in Maven or resolutionStrategy in Gradle.
Building confidence through evidence
Security shouldn't require blind trust. It should be backed by evidence. By publishing these examples, complete with source changes, attestations, build artifacts, test results, and reproducible build instructions, we're making it possible for anyone to independently validate how these patches are produced.
Explore the repository on GitHub: https://github.com/endorlabs/endor-patches
For a deeper dive into the engineering behind Endor Patches, read Henrik Plate's How Endor Patches Are Built and Tested, and visit the Endor Patches documentation to learn how they integrate into your software supply chain.
What's next?
When you're ready to take the next step in securing your software supply chain, here are 3 ways Endor Labs can help:









