Skip to content

[WIP] Replace trivy with grype#2285

Draft
priteau wants to merge 1 commit intostackhpc/2025.1from
replace-trivy
Draft

[WIP] Replace trivy with grype#2285
priteau wants to merge 1 commit intostackhpc/2025.1from
replace-trivy

Conversation

@priteau
Copy link
Copy Markdown
Member

@priteau priteau commented Apr 24, 2026

Assisted-By: Gemini 3 Flash

Assisted-By: Gemini 3 Flash
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request replaces Trivy with Grype and Syft for container image vulnerability scanning and SBOM generation. The changes include updating documentation, configuration files, and the scan-images.sh script to use the new tools and their respective output formats. Feedback focuses on improving the robustness of the shell script, specifically regarding YAML generation for Grype, handling edge cases in jq processing of scan results, and ensuring proper error handling when set -e is active.

Comment thread tools/scan-images.sh
image_vulnerabilities=$(yq ."$imagename"'_allowed_vulnerabilities[]' src/kayobe-config/etc/kayobe/grype/allowed-vulnerabilities.yml 2> /dev/null)

truncate -s 0 .trivyignore # ensure we start from a clean slate
echo "ignore:" > .grype.yaml
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

If both global_vulnerabilities and image_vulnerabilities are empty, the generated .grype.yaml will contain only ignore:. While valid YAML, some parsers might interpret this as a null value rather than an empty list, which could cause issues with Grype. It is safer to initialize it with an empty list ignore: [] or only create the file if there are vulnerabilities to ignore.

Suggested change
echo "ignore:" > .grype.yaml
echo "ignore: []" > .grype.yaml

Comment thread tools/scan-images.sh
.[0].Severity
(map(.artifact.name) | unique | join(";")),
(map(.artifact.locations[]?.path // empty) | unique | join(";")),
.[0].artifact.purl,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

When multiple matches are grouped by vulnerability ID, they might correspond to different artifacts (packages). Using .[0].artifact.purl only captures the PURL of the first match in the group, potentially losing information about other affected packages. It is better to aggregate all unique PURLs in the group.

Suggested change
.[0].artifact.purl,
(map(.artifact.purl) | unique | join(";")),

Comment thread tools/scan-images.sh
(map(.artifact.locations[]?.path // empty) | unique | join(";")),
.[0].artifact.purl,
.[0].vulnerability.id,
(.[0].vulnerability.fix.versions | join(";")),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Similar to the PURL issue, different packages in the same vulnerability group might have different fixed versions. Additionally, if the fix object is null for a match, .[0].vulnerability.fix.versions will cause a jq error. Aggregating the versions and using the optional chaining operator ? is more robust.

Suggested change
(.[0].vulnerability.fix.versions | join(";")),
(map(.vulnerability.fix.versions[]?) | unique | join(";")),

Comment thread tools/scan-images.sh
.[0].vulnerability.id,
(.[0].vulnerability.fix.versions | join(";")),
(.[0].vulnerability.urls | first),
(.[0].vulnerability.severity | ascii_upcase)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

If vulnerability.severity is missing or null, ascii_upcase will throw a jq error. Providing a default value ensures the script continues to run even if the scan data is incomplete.

Suggested change
(.[0].vulnerability.severity | ascii_upcase)
(.[0].vulnerability.severity // "unknown" | ascii_upcase)

Comment thread tools/scan-images.sh
Comment on lines +114 to +118
syft "$image" \
-o spdx-json \
> "$sbom" 2> "$sbom.log"

if [ ! -s "$sbom" ]; then
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Since set -e is active, if syft fails with a non-zero exit code, the script will terminate immediately. This prevents the custom error handling and log output starting at line 120 from being executed. Wrapping the command in an if statement or using || allows the script to catch the error and provide the intended diagnostic information.

Suggested change
syft "$image" \
-o spdx-json \
> "$sbom" 2> "$sbom.log"
if [ ! -s "$sbom" ]; then
if ! syft "$image" -o spdx-json > "$sbom" 2> "$sbom.log" || [ ! -s "$sbom" ]; then
(
echo "ERROR: syft failed or didn't produce the sbom file $sbom for $image" 1>&2
echo "==== syft log ===="
cat "$sbom.log"
) 1>&2
exit 1
else

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