Skip to content

feat: add RapidFort vulnerability provider#1114

Open
vaibhav-rf wants to merge 7 commits intoanchore:mainfrom
vaibhav-rf:feat/rapidfort-provider
Open

feat: add RapidFort vulnerability provider#1114
vaibhav-rf wants to merge 7 commits intoanchore:mainfrom
vaibhav-rf:feat/rapidfort-provider

Conversation

@vaibhav-rf
Copy link
Copy Markdown

feat: add RapidFort vulnerability provider

Summary

Adds a new rapidfort provider that ingests security advisory data from the
RapidFort security-advisories
GitHub repository and normalizes it into vunnel's OSSchema format for consumption
by Grype.

RapidFort advisories are intended for use when scanning RapidFort-curated images
(identified via maintainer metadata) to apply RapidFort-specific version checks
that differ from upstream distro advisories.

What's included

New provider — src/vunnel/providers/rapidfort/

File Purpose
__init__.py Provider and Config classes; registered in the global provider registry
parser.py Advisory loading, normalization, and event-range processing
git.py Shallow-clone wrapper (--depth=1) with retry-backoff for the advisory repo

Supported OS types and version formats:

OS Version format Example namespace
Ubuntu dpkg rapidfort-ubuntu:22.04
Alpine apk rapidfort-alpine:3.15
Red Hat rpm rapidfort-redhat:el9

Namespace isolation: advisories are stored under rapidfort-{os}:{version}
(e.g. rapidfort-ubuntu:20.04) so Grype keeps them separate from standard
upstream distro scans.

Key design decisions

  • Event-based version ranges (mirrors GHSA semantics): each introduced/fixed
    pair in an advisory event becomes a separate FixedIn entry with a
    VulnerableRange field. A single CVE can produce multiple FixedIn entries
    when it affects more than one release branch.
  • Release identifiers: Red Hat advisories carry per-event identifiers (e.g.
    el9, fc36) that are preserved in the Identifier field and reflected in
    VendorAdvisory.AdvisorySummary.
  • Fix availability: integrates with the existing fixdate system to populate
    the Available field on each FixedIn entry.
  • Merge across packages: when the same CVE appears in multiple package files,
    FixedIn entries are merged into a single vulnerability record.

Registration

  • src/vunnel/providers/__init__.py — provider added to the global registry
  • src/vunnel/cli/config.pyConfig added to the Providers dataclass for
    CLI/YAML configuration

Tests — tests/unit/providers/rapidfort/

Test class / function What it covers
TestEventsToRangePairs Range-pair conversion: single, multi-range, introduced-only, fixed-only, deduplication, identifier preservation
TestNormalize Multi-range CVE produces multiple FixedIn entries; Available field present; Red Hat per-range identifiers and VendorAdvisory
TestMergeIntoNamespace Same CVE in two packages merges into one record; distinct CVEs stay separate
TestMapSeverity Case-insensitive known severities; Unknown for None, empty string, unrecognized values
test_provider_schema Full provider output validates against schema-1.1.0.json
test_provider_via_snapshot Regression snapshots for Ubuntu, Alpine, and Red Hat advisory output

Test fixtures cover all three supported OS types:

test-fixtures/
├── input/rapidfort-advisories/OS/
│   ├── ubuntu/curl_advisory.json      # multi-range CVE (2 events)
│   ├── alpine/zlib_advisory.json      # single-range CVE, apk format
│   └── redhat/curl_advisory.json      # per-release identifiers (el9/fc36/fc37)
└── snapshots/
    ├── rapidfort-ubuntu:20.04/
    ├── rapidfort-alpine:3.15/
    └── rapidfort-redhat:el9/

Test plan

  • pytest tests/unit/providers/rapidfort/ — all 17 tests pass
  • Verify vunnel run rapidfort clones the advisory repo and writes results
  • Confirm vunnel list shows rapidfort in the provider list
  • Confirm Grype resolves rapidfort-ubuntu:* / rapidfort-alpine:* /
    rapidfort-redhat:* namespaces when scanning RapidFort-curated images

Signed-off-by: Vaibhav Thatai <[email protected]>
- Extend rapidfort parser for Red Hat OS advisories
- Update unit tests and add rapidfort-redhat:el9 snapshot + input fixtures

Signed-off-by: Vaibhav Thatai <[email protected]>
- Remove unused GitRevision dataclass (copy-paste from ubuntu, never used)
- Fix _events_to_range_pairs called twice per CVE: pass pre-computed
  range_pairs to _build_fixed_in_elements instead of recomputing
- Add alpine/apk fixture + snapshot (third OS type was untested)
- Correct snapshots: VendorAdvisory was missing, breaking snapshot test
- Add tests for _merge_into_namespace, _map_severity, and fc37 VendorAdvisory

Signed-off-by: Vaibhav Thatai <[email protected]>
@vaibhav-rf vaibhav-rf force-pushed the feat/rapidfort-provider branch from 2726aa2 to 487c8be Compare March 31, 2026 04:46
The outer advisory key is the OS version (9), not the release identifier
(el9). Corrects the test fixture, unit test, and snapshot to produce the
rapidfort-redhat:9 namespace that matches real advisory data and grype's
expectations.

Signed-off-by: Vaibhav Thatai <[email protected]>
@vaibhav-rf vaibhav-rf marked this pull request as ready for review March 31, 2026 05:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant