ForemanCveScanner
Plugin to:
- install Trivy/Grype on a host using Foreman Remote Execution (REX)
- run CVE scans via REX and parse the results
- store scan history per host in a dedicated table
- expose scan data via API
- show CVE findings in the Host details UI
- show summary status in the Hosts list
Features
- Support for Trivy and Grype scanners
- REX job templates for installing and running CVE scans
- JSON output parsing with robust handling of chunked stdout
- Per-host scan history with totals and severity counts
- API endpoints for scan history and latest scan
- API endpoint to push external CVE scans
- Host Details card with findings and modal view
- Host Details tab “CVE scans” for full history
- Hosts overview list column “CVE” with quick summary and modal
- Integrated in the Host Status
- Optional Katello integration for managed errata fix availability
- Export scan results as CSV
Installation
See How_to_Install_a_Plugin for how to install Foreman plugins
Usage
- Run the REX job to install Trivy and/or Grype
- Run the REX job to scan a host
- You can configure recurring CVE scans via
Monitor -> Jobs - You can configure the default scanner for the
Run CVE scantemplate viaAdminister -> Settings -> CVE Scanner -> Preferred CVE scanner - The setting
Administer -> Settings -> CVE Scanner -> Run CVE scan after host profiles uploadtakes effect only when Katello is installed and triggers a scan after host profiles uploads using the preferred scanner setting - The setting
Administer -> Settings -> CVE Scanner -> Show CVE fix availability from contentis enabled by default. When Katello is installed, the latest scan view can show whether a matching managed erratum is installable for the host or only applicable. - View results in:
- Hosts overview list column “CVE” (use 'Manage Columns' to enable)
- Host Details card and modal
- Host Details tab “CVE scans”
- Filter hosts by latest CVE scan data with
cve_scanned,cve_total,cve_critical,cve_high,cve_medium,cve_low,cve_scanner,cve_source, andcve_scanned_at
Scanner installation
The Install CVE scanners Remote Execution job installs scanner packages from the host's enabled repositories by default. For Katello-managed hosts, this means trivy and grype can be delivered through the assigned content view/environment.
Set the job parameter install_from_github to true to install the scanner release packages directly from GitHub instead. The trivy_version and grype_version parameters are only used for the GitHub install path.
Katello fix availability
When Katello is installed and Show CVE fix availability from content is enabled, the latest CVE scan is enriched with matching security errata from the host content facet.
The latest scan can show:
-
Installable: a matching erratum is applicable and available in the host's assigned content view environments. The badge links to Foreman's customized Remote Execution flow forkatello_errata_install_by_search. -
Applicable: a matching erratum applies to the host, but is not currently installable from the assigned content view environments. The badge links to the erratum details page. -
No managed fix: no matching managed erratum was found for the CVE/package. -
Unknown: fix availability could not be calculated.
If Katello is not installed, no fix availability data or UI is shown.
External Push API
Push a normalized CVE scan for a host with:
POST /api/v2/hosts/:host_id/cve_scans/import
Required permission:
import_cve_scans
Required payload structure:
{
"cve_scan": {
"scanner": "custom-scanner",
"source": "external",
"scanned_at": "2026-05-14T08:00:00Z",
"findings": [
{
"id": "CVE-2024-8373",
"name": "angular",
"severity": "LOW",
"version": "1.8.2",
"fixed": "open",
"status": "affected",
"title": "angular: From NVD collector",
"published": "2024-09-09T15:15:12.887Z",
"url": "https://avd.aquasec.com/nvd/cve-2024-8373"
},
{
"id": "CVE-2024-9991",
"name": "openssl",
"severity": "CRITICAL",
"version": "3.0.1",
"fixed": "3.0.8",
"status": "affected",
"title": "openssl: Example critical issue",
"published": "2024-10-01T10:00:00Z",
"url": "https://example.test/CVE-2024-9991"
},
{
"id": "CVE-2024-9992",
"name": "curl",
"severity": "HIGH",
"version": "8.5.0",
"fixed": "8.5.1",
"status": "affected",
"title": "curl: Example high issue",
"published": "2024-10-02T10:00:00Z",
"url": "https://example.test/CVE-2024-9992"
},
{
"id": "CVE-2024-9993",
"name": "tar",
"severity": "MEDIUM",
"version": "1.35",
"fixed": "1.36",
"status": "affected",
"title": "tar: Example medium issue",
"published": "2024-10-03T10:00:00Z",
"url": "https://example.test/CVE-2024-9993"
}
]
}
}Notes:
-
scanneris a free-form producer name and can be an unknown external tool -
sourceis stored and shown in the UI, for exampleexternal -
scanned_atis required and is the only scan timestamp used in the UI -
summaryand severity counters are calculated on the server fromfindings -
rawis not part of the public API contract
Retention
You can configure automatic CVE scan cleanup with the plugin setting:
Administer -> Settings -> CVE Scanner -> Delete CVE scans after X days
Behavior:
-
0disables automatic cleanup - scans older than the configured number of days are deleted
- the cleanup runs after imports and can also be triggered manually
Manual cleanup task:
bundle exec rake foreman_cve_scanner:cleanup_scans
Override the configured retention for one run:
bundle exec rake foreman_cve_scanner:cleanup_scans DAYS=30
Contributing
Fork and send a Pull Request. Thanks!
Copyright
Copyright (c) 2024 Bernhard Suttner / ATIX AG
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.