Supply Chain
Dependencies, BOMs, API inventory and the third-party services your code calls.
You will finish this page able to answer the three questions auditors and incident responders actually ask: what is in our software, which parts are exploitable, and who else is in our dependency and vendor graph.
Dependencies
The Dependencies page inventories every package Argus found across your scanned projects.
Columns: Package · Ecosystem · Version · Reachability · License · CVE
Facets: Vulnerabilities (Has vulnerabilities / No vulnerabilities) and Ecosystem (npm, pypi, maven, cargo, conan, gems).
Each row carries the installed version, the latest known version, whether the package is transitive, its license, its reachability verdict, and its vulnerability count. Open a dependency to see every finding attached to it and to act on them, assign, create a ticket, or hand a finding to the fix agent.
Export downloads CSV:
Name, Version, Latest, Ecosystem, Risk, Vulnerabilities, HasVulns, Transitive, Licenses, Project
25 rows per page.
What the inventory reflects
The inventory is the current state of your manifests, not a running total.
Every scan reconciles it. Packages the scan no longer finds are removed, so upgrading a dependency does not leave the old version behind, and a package you dropped stops appearing. Where a package is resolved from more than one source, a lockfile version always wins over a version range in a manifest, because a range is a floor and a lockfile is a record of what was installed.
Pruning fails closed. If a scan finishes without resolving any dependencies at all, Argus prunes nothing and keeps what it already had. A scanner that failed must never be able to empty your inventory. You will see the previous inventory unchanged rather than an empty page, and the scan itself will report the failure.
A package appearing at two versions is not necessarily an error. Nested dependency trees legitimately install two versions of one package, and both are reported when both are genuinely present.
Which ecosystems get advisory matching
Argus parses these lockfiles and matches them against OSV.dev:
package-lock.json · yarn.lock · pnpm-lock.yaml · requirements.txt · requirements-dev.txt · Pipfile.lock · go.sum · Gemfile.lock · Cargo.lock · composer.lock
Java and .NET packages appear in your SBOM (via the SBOM generator) and in container scan results, but Argus does not yet parse pom.xml, Gradle files or .csproj for advisory matching.
Reachability on dependencies
Every dependency finding is classified reachable, unreachable or unknown. This is the single biggest noise reduction available in SCA, an unreachable CVE stays visible but sinks to the bottom of your priority order. See Concepts.
Malicious packages and typosquats
Argus screens every dependency against OSV's malicious-package feed, and compares its name against a curated table of popular packages. A name one edit away from a popular package, the classic typosquat, and the slopsquat names AI assistants hallucinate, is flagged.
To stop a bad package before it is installed, wire the scan_package tool into your AI assistant. See Integrations.
Checking provenance
Argus can check whether a published package carries build provenance and a SLSA attestation:
curl -sS -X POST "$ARGUS_URL/api/graphql" \
-H "Authorization: Bearer argus_live_xxx" \
-H "content-type: application/json" \
-d '{"query":"{ CheckProvenance(package: "sigstore", ecosystem: "npm") { supported hasProvenance signed slsaLevel builderId sourceRepo predicateTypes summary } }"}'
Bills of materials
The BOMs page holds every bill of materials Argus generated, one per project per scan.
Tabs: All · SBOM · AIBOM · CBOM · HBOM · QBOM Columns: Project · Type · Standard · Components · Updated · Export
What Argus generates
| BOM | Status | What is in it |
|---|---|---|
| SBOM | Generated on every scan | The full component inventory of the repository, name, version, purl, license, scope, and genuine artifact hashes recovered from lockfile integrity data. Emitted as CycloneDX 1.6 and SPDX 2.3 |
| CBOM | Generated when cryptography is detected | One component per detected cryptographic algorithm family, AES, RSA, SHA family, ECDSA, Diffie-Hellman, MD5, each with the real file:line locations where it was found, and NIST post-quantum classification. Detection is source-pattern based, so treat it as an inventory, not an exhaustive crypto audit. Marked beta |
| QBOM | Generated when quantum-vulnerable cryptography is detected | The strict subset of the CBOM that is quantum-vulnerable, RSA, ECDSA and Diffie-Hellman. Adds a quantum-readiness verdict, a harvest-now-decrypt-later exposure flag, and references to FIPS 203/204/205. Marked beta |
| HBOM | Generated when infrastructure-as-code is present | Container and cloud-infrastructure inventory derived from your Terraform resources, Docker Compose services, Dockerfile base images and Kubernetes workloads. This is deployed infrastructure, explicitly not physical hardware |
| AIBOM | Coming soon | Not yet produced as a reliable AI/ML model inventory. Do not rely on it |
A specialised BOM is only written when it has content, an empty CBOM or HBOM is omitted rather than padded with a zero-component record.
Exporting
Every BOM offers the same five formats:
| Format | File |
|---|---|
| CycloneDX JSON | <project>-<subtype>-cyclonedx.json |
| CycloneDX XML | <project>-<subtype>-cyclonedx.xml |
| SPDX JSON | <project>-<subtype>-spdx.json |
| SPDX Tag-Value | <project>-<subtype>.spdx |
| CSV | <project>-<subtype>-components.csv |
The CSV columns are Name, Version, Type, PURL, License, Scope, Hash.
Export from the API:
curl -sS -X POST "$ARGUS_URL/api/graphql" \
-H "Authorization: Bearer argus_live_xxx" \
-H "content-type: application/json" \
-d '{
"query": "query Export($id: ID!, $f: String!) { ExportBOM(id: $id, format: $f) { filename mimeType content } }",
"variables": { "id": "<bom-id>", "f": "cyclonedx-json" }
}'
Valid format values: cyclonedx-json, cyclonedx-xml, spdx-json, spdx-tv, csv.
Comparing two BOMs
Use Compare on the BOMs page, or the API, to diff two BOMs and see what was added, removed and version-bumped:
{
GetBOMDiff(bomId1: "<older>", bomId2: "<newer>") {
added removed updated unchanged
components { name changeType oldVersion newVersion }
}
}
Importing a BOM
Bring in a BOM produced elsewhere, a vendor's SBOM, or one from a build system Argus does not scan:
mutation {
ImportBOM(
projectId: "<project-id>"
content: "<the BOM document as a string>"
format: "cyclonedx"
bomSubtype: "SBOM"
) { id project components bomType status }
}
bomSubtype accepts SBOM, CBOM, QBOM, HBOM, AIBOM.
VEX
VEX (Vulnerability Exploitability eXchange) tells downstream consumers which CVEs actually affect your product. Argus drives its VEX statements from reachability, so an unreachable dependency CVE is published as not_affected with a proper justification instead of alarming everyone who consumes your SBOM.
Generating VEX
BOMs → VEX ▾ → Generate VEX, or:
curl -sS -X POST "$ARGUS_URL/api/graphql" \
-H "Authorization: Bearer argus_live_xxx" \
-H "content-type: application/json" \
-d '{
"query": "query Vex($p: ID!, $f: String) { GenerateVex(projectId: $p, format: $f) { filename mimeType content } }",
"variables": { "p": "<project-id>", "f": "openvex" }
}'
Formats: openvex (OpenVEX v0.2.0, the default) and cyclonedx-vex (CycloneDX 1.6 VEX).
How a finding maps to a statement:
| Finding | VEX status | Justification |
|---|---|---|
| Marked false positive | not_affected | component_not_present |
| Resolved / fixed | fixed | - |
| Unreachable | not_affected | Code-not-reachable, with the evidence string |
| Open and reachable | affected | - |
VEX statements key on a vulnerability identifier, CVE-…, GHSA-…, GO-…, PYSEC-…, RUSTSEC-… or OSV-…. Findings without one are omitted.
Importing VEX
BOMs → VEX ▾ → Import VEX consumes an upstream VEX document and suppresses the CVEs its supplier has declared not-affected:
mutation {
ImportVex(projectId: "<project-id>", content: "<vex document>") {
statements matchedCves suppressed message
}
}
Third-party inventory
The Third Parties page lists the external services your code actually calls, discovered from your source during scanning.
KPIs: Vendors tracked · Critical risk · With vulnerabilities · Data sharing
Filters: Risk level (Critical / High / Medium / Low) · Classification (Analytics, Authentication, CDN, Payment, Communication, Storage, AI/ML, Security, External API) · Projects
Each vendor card opens a detail sheet with Overview, API Endpoints and Projects tabs.
Read the banner. This page is detected services, not a security assessment. The vendor, its category and the projects that call it come from your scanned code and are real. TLS version, authentication, data-sharing and vulnerability status are not independently verified and read
Not assessed. "0 with vulnerabilities" means "not evaluated", not "clean".
Export downloads CSV: Vendor, Category, Risk, Endpoints, DataShared, AuthRequired, TLS, HasVulns, Projects, LastSeen.
API inventory
Scanning also extracts the HTTP routes your own code exposes. The API Inventory page lists them.
Columns: Method · Endpoint · Project · Auth · Category · PII · Last seen · Risk
Filters: HTTP Method (GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD) · Risk · PII (Contains PII) · Authentication (Authenticated, Open / no auth, Not determined). Counts are computed over the whole result set, not just the visible page.
The three authentication states
Argus reports what it can prove, and says so when it cannot:
| State | Meaning |
|---|---|
| Authenticated | An auth construct was found that is attributable to this specific route. |
| Open / no auth | The route was analysed and no authentication was found. This is a finding. |
| Not determined | Authentication machinery exists in the file, but Argus could not tie it to this route. Not a finding, an unanswered question. |
Why the third state matters. Before 2026-08-07 the inventory had only two buckets, and anything not provably authenticated was labelled Open / no auth. On a live estate of 447 endpoints that reported 383 as unauthenticated; the true figure was 96, with 287 simply undetermined. A scanner that cannot distinguish "I checked and it is open" from "I could not check" produces false alarms at scale, and a queue full of them is a queue nobody works.
Risk scoring is deliberately more conservative than the label. An endpoint whose auth is
undetermined is still scored as though it were open, because erring toward higher risk is the right
default for a security tool. So you may see a Not determined endpoint carrying a High or Critical
risk. That is intended. The risk assumes the worst; the label refuses to assert something
unproven.
Open an endpoint to see:
- Overview: risk level, category, auth, PII, third party, last seen, status, namespace
- Remediate: the findings linked to this endpoint, each with Assign to Agent, Assign and Create ticket
Bulk actions: Send to Jira (creates tickets for the selected endpoints' linked findings) and Export selected.
Export downloads CSV: Method, Endpoint, Authenticated, PII, Risk, ThirdParty, Category, Status, Project, LastSeen.
25 rows per page.
Compliance evidence packs
Argus assembles a framework-mapped evidence pack from your project's BOMs and its latest completed scan. Everything in the pack is derived from scan data. Nothing is asserted.
| Framework | Key |
|---|---|
| CERT-In | CERT-In (default) |
| US Executive Order 14028 | EO-14028 |
| NIST SSDF | NIST-SSDF |
| EU Cyber Resilience Act | EU-CRA |
Download from Compliance, or over REST:
curl -sS "$ARGUS_URL/api/compliance/<project-id>?framework=EU-CRA&download=1" \
-H "Authorization: Bearer argus_live_xxx" \
-o evidence-pack.json
Drop &download=1 to get the same JSON inline. The same data is available over GraphQL as GenerateCompliancePack(projectId, framework).
A pack contains the BOM inventory across all subtypes, a scan attestation naming the tools that ran and the findings they produced, and the per-control mapping with its evidence.
SARIF export
For any tool that speaks SARIF, GitHub code scanning, IDE plugins, your own dashboards:
curl -sS -X POST "$ARGUS_URL/api/graphql" \
-H "Authorization: Bearer argus_live_xxx" \
-H "content-type: application/json" \
-d '{"query":"query($p: ID!){ ExportSarif(projectId: $p) { filename mimeType content } }","variables":{"p":"<project-id>"}}'
Resolved and false-positive findings are excluded.
Next
- Policies and gates, turn this inventory into a build decision
- API reference, automate the exports