Concepts
How Argus works
Argus runs as a pipeline of six well-separated stages. Each stage has a single job, and each hands a precise, in-memory result to the next.
The pipeline
The run command performs every stage in order. The individual subcommands (scan, fix, mr) each stop at a particular point, which is useful when you want visibility without changes, or patches without publication.
pom.xml
→ Generate SBOM (mvn cyclonedx:makeAggregateBom)
→ Match advisories (every enabled advisory source; OSV.dev by default)
→ Plan remediation (strategy ladder)
→ Patch pom.xml (byte-level, format-preserving)
→ Qualify (mvn validation gate)
→ Publish & reconcile (GitLab merge requests)1. Discover
Argus asks Maven for an aggregate CycloneDX SBOM using the cyclonedx-maven-plugin. Because the SBOM comes from Maven’s own resolution, it reflects the real, fully resolved dependency graph, direct and transitive, exactly as your build sees it. Argus parses that SBOM into an in-memory graph with forward and reverse edges, so it can answer questions like “is this dependency direct?” and “what path brings it in?”. See SBOM & vulnerabilities for detail.
2. Match
Every component is sent to OSV.dev in batches via the querybatch endpoint, scoped to the Maven ecosystem. Argus then hydrates each advisory it gets back with the full record, so it knows the affected version ranges, the fixed versions, the severity, and whether the advisory has been withdrawn. Hydrated advisories are cached on disk so repeated runs stay fast.
OSV is the default source, not the only one. The advisory_sources block names every database Argus consults, in a precedence you choose: OSV and the advisories you declare by hand. All enabled sources are queried at the same time and their findings are merged into one list before planning starts, so the rest of the pipeline never knows or cares where an advisory came from. The report and the merge request do say.
3. Plan
For each advisory, the strategy ladder decides how to fix it. The choice depends on whether the vulnerable dependency is direct or transitive, and whether a parent POM hard-pins its version. The planner also chooses the target version using Maven’s own version semantics (never naive SemVer) and refuses pre-release versions.
4. Patch
Argus turns each plan into a set of byte-level edits and splices them into the POM. It never serialises an XML tree, so comments, indentation, and element ordering survive untouched. See Format-preserving patches.
5. Qualify
Before a patch is allowed anywhere near a merge request, Argus validates it by running Maven against the patched POM in an isolated workspace. The strictness of this gate is configurable, from “the sources still compile” to “the tests still pass”. See Validation policies.
6. Publish & reconcile
Qualified patches become GitLab merge requests, each on its own branch and labelled by severity. On every run Argus also reconciles: merge requests it previously opened that no longer correspond to outstanding work are closed, so the set of open remediation MRs always matches reality. See Merge requests.
Why determinism matters
Given the same project and the same advisories, Argus makes the same decisions every time. The strategy ladder is a fixed set of ranked rules, not a heuristic or a model, and version selection follows Maven’s ordering precisely. That predictability is what makes Argus safe to run unattended in CI: you can review a single example and trust that the thousandth run behaves like the first.