Skip to content

Add Root IO vulnerability data provider#963

Open
chait-slim wants to merge 4 commits intoanchore:mainfrom
chait-slim:feat/rootio-provider-2
Open

Add Root IO vulnerability data provider#963
chait-slim wants to merge 4 commits intoanchore:mainfrom
chait-slim:feat/rootio-provider-2

Conversation

@chait-slim
Copy link

This adds a new provider for Root IO vulnerability data, which provides
security information for Root IO patched packages across multiple
ecosystems (Debian, Ubuntu, Alpine, NPM, PyPI).

Implementation details:

  • Fetches OSV 1.6.1 format data from Root IO API (api.root.io/external/osv)
  • Implements NAK pattern: rootio- prefixed packages only match Root IO vulnerabilities
  • Supports ecosystem-specific version suffixes (.root.io.N for Debian/Ubuntu, -root.io.N for NPM, +root.io.N for PyPI)
  • Provider class in src/vunnel/providers/rootio/init.py
  • OSV record parser in src/vunnel/providers/rootio/parser.py
  • Registered in src/vunnel/providers/init.py and src/vunnel/cli/config.py

@willmurphyscode willmurphyscode self-assigned this Jan 13, 2026
@willmurphyscode willmurphyscode moved this to In Review in OSS Jan 13, 2026
}
}
],
"database_specific": {"source": "Root"}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should also assert something like:

  if "database_specific" not in vuln_entry:
      vuln_entry["database_specific"] = {}
  if "anchore" not in vuln_entry["database_specific"]:
      vuln_entry["database_specific"]["anchore"] = {}
  vuln_entry["database_specific"]["anchore"]["record_type"] = "advisory"

has been done. Otherwise, grype-db doesn't know to emit unaffectedPackageHandles and this data just makes affected package handles and the NAKS don't do anything.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

  This adds a new provider for Root IO vulnerability data, which provides
  security information for Root IO patched packages across multiple
  ecosystems (Debian, Ubuntu, Alpine, NPM, PyPI).

  Implementation details:
  - Fetches OSV 1.6.1 format data from Root IO API (api.root.io/external/osv)
  - Implements NAK pattern: rootio- prefixed packages only match Root IO vulnerabilities
  - Supports ecosystem-specific version suffixes (.root.io.N for Debian/Ubuntu,
    -root.io.N for NPM, +root.io.N for PyPI)
  - Provider class in src/vunnel/providers/rootio/__init__.py
  - OSV record parser in src/vunnel/providers/rootio/parser.py
  - Registered in src/vunnel/providers/__init__.py and src/vunnel/cli/config.py

Signed-off-by: Chai Tadmor <chai.tadmor@root.io>
….py _normalize()

2. Added comprehensive tests to verify the metadata is set correctly
3. Updated all 5 snapshot fixtures with the new metadata

Signed-off-by: Chai Tadmor <chai.tadmor@root.io>
@chait-slim chait-slim force-pushed the feat/rootio-provider-2 branch from 09e61c6 to 85f1e1d Compare January 15, 2026 13:52
# Fix date patching is optional and requires authentication

# Fetch and process each OSV record
for osv_id in osv_ids:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make this concurrent in some way. Right now this provider does ~9K sequential, blocking http gets, which makes it very slow for a relatively small amount of data. Many of the other providers have some concurrent.futures.ThreadPoolExecutor use and a config that controls the concurrency (and sets a default higher than 1). Please imitate that pattern here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably fine to enter a concurrent section that pulls down all the osv docs and then process them sequentially, which is probably easier than trying to get the entire record normalized and processed concurrently.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added concurrency

- name: github
use_cache: true
images:
- cr.root.io/cassandra@sha256:b3cc918a6a364af0a6b0a45becef0d0979db7e604751fad627ec2a94945b4e03
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you changed this image to be on a different repo?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Signed-off-by: Chai Tadmor <chai.tadmor@root.io>
@chait-slim chait-slim force-pushed the feat/rootio-provider-2 branch from c9e7a9e to d92900e Compare January 15, 2026 18:52
- Switched from private ECR to public Docker Hub images for accessibility
- Added 3 FP labels for ubuntu:22.04 image (CVE-2016-20013 x2, CVE-2021-46848)
- Added 3 FP labels for cassandra image (CVE-2016-20013 x3)
- Demonstrates Root IO patch prevention mechanism
- Reference scan finds vulnerabilities but Root IO-enhanced scan correctly excludes them
- Updated .yardstick.yaml and config.yaml to use docker.io/rootpublic images

Images:
- docker.io/rootpublic/ubuntu:22.04@sha256:1390a26823a5a761dfbb7f591ae74a71afd8e23583a2f0c58dca6943b606f6d5
- docker.io/rootpublic/cassandra:latest@sha256:02272b14efbe14e70ee5512ce707c4e300d3c1813f0e5df9562512c1b96be835

Signed-off-by: Chai Tadmor <chai.tadmor@root.io>
@willmurphyscode
Copy link
Contributor

Hi @chait-slim,

I was just running this locally to check on it, and the quality gate currently fails like this:

2026-01-28 10:43:44,159 [INFO] Running comparison against labels...
   Results used for image docker.io/rootpublic/cassandra@sha256:02272b14efbe14e70ee5512ce707c4e300d3c1813f0e5df9562512c1b96be835:
    ├── 87dd34c5-da71-4716-8020-f557cbfba205 : grype[custom-db]@v0.106.0-1-gc17d5ab3 (custom-db)  against docker.io/rootpublic/cassandra@sha256:02272b14efbe14e70ee5512ce707c4e300d3c1813f0e5df9562512c1b96be835
    └── 752339e3-85cd-45ad-b3ff-5af5a85a0fd3 : grype[reference]@v0.106.0-1-gc17d5ab3 (reference)  against docker.io/rootpublic/cassandra@sha256:02272b14efbe14e70ee5512ce707c4e300d3c1813f0e5df9562512c1b96be835
Deltas for docker.io/rootpublic/cassandra@sha256:02272b14efbe14e70ee5512ce707c4e300d3c1813f0e5df9562512c1b96be835:
Match differences between tooling (with labels):
   TOOL PARTITION                              PACKAGE                    VULNERABILITY   LABEL      COMMENTARY
   grype[reference]@v0.106.0-1-gc17d5ab3 ONLY  libc-bin@2.35-0ubuntu3.11  CVE-2016-20013  (unknown)
   grype[reference]@v0.106.0-1-gc17d5ab3 ONLY  libc6@2.35-0ubuntu3.11     CVE-2016-20013  (unknown)
   grype[reference]@v0.106.0-1-gc17d5ab3 ONLY  locales@2.35-0ubuntu3.11   CVE-2016-20013  (unknown)

--------------------------------------------------------------------------------
   Results used for image docker.io/rootpublic/ubuntu@sha256:1390a26823a5a761dfbb7f591ae74a71afd8e23583a2f0c58dca6943b606f6d5:
    ├── 2938550e-dc92-4001-a9b3-dcf8fa0ef290 : grype[custom-db]@v0.106.0-1-gc17d5ab3 (custom-db)  against docker.io/rootpublic/ubuntu@sha256:1390a26823a5a761dfbb7f591ae74a71afd8e23583a2f0c58dca6943b606f6d5
    └── 723db393-6186-4b0b-8368-51a685f0f4f6 : grype[reference]@v0.106.0-1-gc17d5ab3 (reference)  against docker.io/rootpublic/ubuntu@sha256:1390a26823a5a761dfbb7f591ae74a71afd8e23583a2f0c58dca6943b606f6d5
Deltas for docker.io/rootpublic/ubuntu@sha256:1390a26823a5a761dfbb7f591ae74a71afd8e23583a2f0c58dca6943b606f6d5:
Match differences between tooling (with labels):
   TOOL PARTITION                              PACKAGE                       VULNERABILITY   LABEL      COMMENTARY
   grype[reference]@v0.106.0-1-gc17d5ab3 ONLY  libc-bin@2.35-0ubuntu3.11     CVE-2016-20013  (unknown)
   grype[reference]@v0.106.0-1-gc17d5ab3 ONLY  libc6@2.35-0ubuntu3.11        CVE-2016-20013  (unknown)
   grype[reference]@v0.106.0-1-gc17d5ab3 ONLY  libtasn1-6@4.18.0-4ubuntu0.2  CVE-2021-46848  (unknown)

--------------------------------------------------------------------------------

Reasons for quality gate failure:
   - current indeterminate matches % is greater than 90%: candidate=100.00% image=docker.io/rootpublic/cassandra@sha256:02272b14efbe14e70ee5512ce707c4e300d3c1813f0e5df9562512c1b96be835 (docker.io/rootpublic/cassandra@sha256:02272b14efbe14e70ee5512ce707c4e300d3c1813f0e5df9562512c1b96be835)
   - current indeterminate matches % is greater than 90%: candidate=100.00% image=docker.io/rootpublic/ubuntu@sha256:1390a26823a5a761dfbb7f591ae74a71afd8e23583a2f0c58dca6943b606f6d5 (docker.io/rootpublic/ubuntu@sha256:1390a26823a5a761dfbb7f591ae74a71afd8e23583a2f0c58dca6943b606f6d5)

I think these are the missing labels that I was asking for at anchore/vulnerability-match-labels#167 (comment) - if you agree that these are things that rootio patched, they should be labeled as false positives in that PR. I'm also sort of surprised to see differences in these packages, which don't look like RootIO packages to me. Am I missing something?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Review

Development

Successfully merging this pull request may close these issues.

2 participants