Skip to content

Conversation

@tommartensen
Copy link
Collaborator

@tommartensen tommartensen commented Dec 8, 2025

Description

Partners with stackrox/stackrox#17985

  • Workflow now scans Konflux and GHA-built images.
  • Workflow now triggered by new tags automatically (can be manually dispatched for other tags or as required).
  • Workflow uses composite action to stay DRY.

This PR mostly extracts the existing image scan logic into a composable action.

Validation

https://github.com/stackrox/stackrox/actions/runs/20063752468

Why did I not test with test-gh-actions?

The workflow there still uses quay.io ratings: https://github.com/stackrox/test-gh-actions/blob/main/.github/workflows/scripts/check-image-vulnerabilities.py and wasn't updated after stackrox/stackrox#10836.

@tommartensen tommartensen self-assigned this Dec 8, 2025
@tommartensen tommartensen changed the title ROX-30730: add action for iamge-vulnerability-check ROX-30730: add action for image-vulnerability-check Dec 8, 2025
@tommartensen tommartensen marked this pull request as ready for review December 8, 2025 15:40
@tommartensen tommartensen requested a review from a team as a code owner December 8, 2025 15:40
@tommartensen tommartensen requested a review from msugakov December 8, 2025 15:50
Copy link

@msugakov msugakov left a comment

Choose a reason for hiding this comment

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

Skipped readme and some smaller details in the action.

@tommartensen tommartensen marked this pull request as draft December 9, 2025 10:41
@tommartensen
Copy link
Collaborator Author

tommartensen commented Dec 9, 2025

@msugakov
I have refactored the action into a bash script, that made it easier for me to address your concerns.

The action now:

  • allows for repository to be specified, ie allows rhacs-eng/... and stackrox-io/...
  • doesn't have superfluous outputs, but still uploads the artifact to the workflow run. I am including this for a future workflow that: downloads all scan results -> collects vulnerable images -> suggests fixes)

The script has the following improvements:

  • Consider moderate, important, critical CVEs
  • Always displays a status (❌ or ✅ ) with description and a table with total and fixable vulnerability count per category. One of the problems I had with the previous version of the workflow was that this information needed to be parsed by human manually.
  • Fail the action if there are fixable important or critical CVEs
  • Print a collapsed vulnerability table in Markdown with full details.
    • GH automatically links CVEs to GHSA where available.

You can check how this looks in the summary for https://github.com/stackrox/stackrox/actions/runs/20063752468

@tommartensen tommartensen marked this pull request as ready for review December 9, 2025 12:54
@tommartensen tommartensen requested a review from msugakov December 9, 2025 12:54
Copy link

@msugakov msugakov left a comment

Choose a reason for hiding this comment

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

Made a pass. I'll likely find something else in subsequent iterations.

@tommartensen tommartensen force-pushed the tm/ROX-image-vuln-check branch from e060327 to e6f53b0 Compare December 13, 2025 11:45
@msugakov msugakov changed the title ROX-30730: add action for image-vulnerability-check ROX-30730: add scan-image-vulnerabilities action Dec 15, 2025
Copy link

@msugakov msugakov left a comment

Choose a reason for hiding this comment

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

Sorry, could cover only a small part today. Please expect follow-ups.

Comment on lines 13 to 19
IMAGE="${1:-}"
SUMMARY_PREFIX="${2:-}"
local result_path="scan-result.json"

check_not_empty \
IMAGE \
SUMMARY_PREFIX

Choose a reason for hiding this comment

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

I don't know bash pass-by-name semantics and so the question: would check_not_empty still work if IMAGE and SUMMARY_PREFIX are both declared local?

In my tiny test, it seems to work:

$ cat a.sh
#!/usr/bin/env bash

set -euo pipefail

function main() {
	local image="blah"
	check image
}

function check() {
	typeset -n VAR="$1"
	echo "it is: $VAR"
}

main

$ ./a.sh
it is: blah

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes it works - what is your suggestion or concern here?

Choose a reason for hiding this comment

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

  IMAGE="${1:-}"
  SUMMARY_PREFIX="${2:-}"

aren't declared as local. Please declare them as local.

Copy link

@msugakov msugakov left a comment

Choose a reason for hiding this comment

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

Finished the full pass.


Required: Yes
Prefix for the vulnerability report in the GitHub step summary. Use this to help users of the action classify images into groups when multiple matrix scans are performed in a workflow.

Choose a reason for hiding this comment

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

Suggested change

(keeping a newline but deleting a blank tab)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done in 303fbdb, there was one more whitespace to fix.

The action integrates with the [stackrox/central-login](https://github.com/stackrox/central-login) action, which uses OIDC login for authentication of the `roxctl` CLI.
The ACS Central needs to be configured to allow exchanging tokens from GitHub Actions workflow runs.

Additionally, an image integration for Quay.io needs to be configured in the ACS Central.

Choose a reason for hiding this comment

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

Suggestion:

Suggested change
Additionally, an image integration for Quay.io needs to be configured in the ACS Central.
Additionally, an image integration for Quay.io must be configured in the ACS Central so that it can pull images requested for scanning.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done in 303fbdb

function print_vulnerability_status() {
local -n vuln_counts_ref=$1
# Prints the vulnerability status and an overview table of the findings counts.
function print_findings_status() {

Choose a reason for hiding this comment

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

How about?

Suggested change
function print_findings_status() {
function print_summary() {

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done in 303fbdb

local -n fixable_counts_ref=$2

if (( fixable_counts_ref[CRITICAL] > 0 || fixable_counts_ref[IMPORTANT] > 0 )); then
if [ "$(assert_fixable_findings_present fixable_counts_ref)" = "true" ]; then

Choose a reason for hiding this comment

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

Please use [[ instead of [ in bash. There's a couple places to fix.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done in 303fbdb

# Prints a markdown table of the findings, sorted by severity with fixable findings first.
# Each row contains left, right and column separators added by jq's join function.
function print_vulnerabilities_table() {
function print_findings_table() {

Choose a reason for hiding this comment

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

Optional suggestion:

Suggested change
function print_findings_table() {
function print_details_table() {

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done in 303fbdb

Comment on lines 100 to 108
# Asserts if any fixable findings of relevant severity are present.
function assert_fixable_findings_present() {
local -n fixable_counts_map="$1"
if (( fixable_counts_map[CRITICAL] > 0 || fixable_counts_map[IMPORTANT] > 0 )); then
echo "true"
else
echo "false"
fi
}
Copy link

@msugakov msugakov Dec 19, 2025

Choose a reason for hiding this comment

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

Sorry, this one's going to be a bit vague as I just throw a code suggestion:

Suggested change
# Asserts if any fixable findings of relevant severity are present.
function assert_fixable_findings_present() {
local -n fixable_counts_map="$1"
if (( fixable_counts_map[CRITICAL] > 0 || fixable_counts_map[IMPORTANT] > 0 )); then
echo "true"
else
echo "false"
fi
}
# Checks if any fixable findings of relevant severity are present.
function are_blocking_vulns_present() {
local -n fixable_counts="$1"
if (( fixable_counts[CRITICAL] > 0 || fixable_counts[IMPORTANT] > 0 )); then
return 0
else
return 1
fi
}

0 means success or "yes", no-zero means failure, or "no". Perhaps it can be done via just return (( fixable_counts[CRITICAL] > 0 || fixable_counts[IMPORTANT] > 0 )) but I haven't tried.

After this, you can simply write

if are_blocking_vulns_present fixable_counts_ref; then
  # ...

and no need to compare strings.

The logic is still invert of what it should be, 0 == "clean", no-zero == "failure", but we need a good function name and I can't come up with one at the moment. Perhaps you can?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done in 35cf37d.
I think that are_blocking_vulns_present sufficiently describes the content of the function.

The variable needs to be named fixable_counts_map if we want to keep the local -n. If it was named fixable_counts, it would create a circular dependency.

@tommartensen tommartensen requested a review from msugakov January 5, 2026 17:44
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.

2 participants