Concepts

Direct parent upgrades

When a direct dependency already released a version that fixes its vulnerable transitive, Argus can upgrade that dependency instead of pinning the transitive leaf.

What it is

The classic strategy ladder fixes a vulnerable transitive by adding an OVERRIDE or EXCLUDE+ADD patch for the vulnerable package. That remains the safety net. A direct parent upgrade tries a cleaner path first: bump the dependency your application actually declares, then prove the new resolved graph no longer contains the vulnerable transitive.

This is different from an anchor upgrade. Anchors are BOMs, parent POMs, or managed dependencies that govern versions. Direct parent upgrades target an ordinary direct dependency on the path to the vulnerable component.

Example

If an application depends on json-utils:2.0.1, Maven resolves vulnerable Jackson 3.0.3 through that library. The maintainer fixed the issue in json-utils:2.6.0, which naturally resolves Jackson 3.2.0. Argus prefers the parent upgrade when it verifies, so the merge request updates the library the developer recognises.

text
# Before
app -> io.gitlab.guisseppe:json-utils@2.0.1 -> tools.jackson.core:jackson-databind@3.0.3

# Preferred fix when proven
io.gitlab.guisseppe:json-utils 2.0.1 -> 2.6.0

# Resulting graph
app -> io.gitlab.guisseppe:json-utils@2.6.0 -> tools.jackson.core:jackson-databind@3.2.0

Proof gate

Argus does not assume a newer parent is safe. It enumerates same-major published parent versions, applies any version ceiling, materialises a candidate POM, re-runs SBOM resolution, re-queries advisories, rejects candidates that introduce new advisories, and then qualifies the candidate with mvn verify.

Since 2.9.0 Argus probes the newest candidate first. If bumping the parent to its newest version does not move the vulnerable transitive’s resolved version (because it is pinned by a <dependencyManagement> entry, an imported BOM, or a repackaged internal artifact), no candidate can, so Argus abandons the trial after a single re-resolution and logs the pin instead of trialling every version. Advisory clearance is judged against the transitive’s resolved version, so a CVE that also affects a sibling artifact the bump did not move no longer blocks a genuine fix.

Controls

Direct parent upgrades are enabled by default. Set ARGUS_PARENT_UPGRADE=off or the GitLab component parent_upgrade input to off when you need to skip the trial loop.

Shell
# Direct parent upgrades run by default.
argus run --pom pom.xml

# Use the classic transitive override/exclude ladder only.
ARGUS_PARENT_UPGRADE=off argus run --pom pom.xml