Concepts
SBOM & vulnerabilities
Argus reasons about the real, fully resolved dependency graph (the one your build actually produces) and matches every component in it against the OSV.dev advisory database.
The SBOM
The first thing Argus does is ask Maven for an aggregate CycloneDX software bill of materials, using the cyclonedx-maven-plugin. This matters: the SBOM is produced by Maven’s own resolver, so it reflects exactly what your project builds against: the same version conflict resolution, the same effective POM, the same transitive closure. Argus is never guessing at your graph from the declared dependencies; it reads the graph Maven resolved.
A graph, not a list
Argus parses the SBOM into an in-memory dependency graph with edges in both directions. Forward edges answer “what does this component pull in?”; reverse edges answer “what brings this component into my build?”. That second question is the one that matters for remediation. When a vulnerable library sits three levels down, Argus can walk the reverse edges to find the direct dependency that introduced it, which is exactly the information the strategy ladder needs to decide between an override and an exclusion. The graph also tells Argus, unambiguously, whether a given dependency is declared directly in your POM or arrived transitively.
Matching against OSV
Every component in the graph is checked against OSV.dev, the open vulnerability database. Argus sends components in batches through the querybatch endpoint, scoped to the Maven ecosystem, which keeps the round-trips few even on large projects. For each advisory that comes back, Argus records the affected coordinates, the version range the vulnerability was introduced in, and the version that fixes it:
{
"group_id": "org.apache.commons",
"artifact_id": "commons-text",
"introduced": "1.0",
"fixed": "1.10.0"
}OSV is the first entry in the default advisory-source list, not a hard-wired choice. advisory_sources also carries the advisories you declare in config.yml, so an advisory OSV has not mapped yet still reaches the planner, in the same record shape shown above. When both report the same advisory on the same coordinate they are merged into one record that lists both, and the higher stated fix wins.
Hydration and caching
The batch query returns advisory identifiers, not full records. Argus then hydrates each one, fetching the complete advisory so it knows the precise affected ranges, the fixed versions, the severity score, and whether the advisory has been withdrawn. Each lookup is resolved through three tiers in order: an in-memory memo for the current run, an on-disk cache under .argus-cache/ (default 24-hour time-to-live), then the OSV network. Repeated runs in the same day reuse the disk cache and skip the network entirely, so a re-scan is bounded by your Maven build rather than by OSV round-trips. Both the cache location and its lifetime are configurable; see Environment variables and Global flags.
The in-memory memo matters within a single run because Argus revisits the advisory database in several phases: the initial scan, anchor-upgrade trials, the final remediation pass, and stale-override detection. Once a record has been hydrated, every later phase reuses the parsed result without re-reading the disk or re-parsing the JSON.
Parallel hydration
On a cold cache (the first run of a project, or a fresh CI runner) the per-advisory fetches are issued through a bounded worker pool rather than one at a time. A project with several dozen advisories no longer waits on dozens of sequential round-trips; the fetches overlap, and results are reassembled in their original order. The pool size defaults to 8 and is set by ARGUS_OSV_CONCURRENCY.
The default is deliberately conservative: it shortens cold-cache hydration without firing an aggressive burst at OSV. When OSV does push back with a 429 Too Many Requests, Argus honours the Retry-After header and backs off that request individually. Behind a strict corporate proxy or a tightly rate-limited OSV mirror, set ARGUS_OSV_CONCURRENCY=1 to restore fully sequential hydration.
Withdrawn advisories
Advisories are sometimes retracted: a false positive, a re-scoped record, a duplicate. Because Argus hydrates the full record, it sees the withdrawal marker and drops the advisory rather than opening a merge request for a vulnerability that no longer stands. This is part of what keeps the output trustworthy: the set of remediations Argus proposes corresponds to advisories that are still live and still affect your resolved graph.