From 472057397d07949fd679b05c678665292adc6cd1 Mon Sep 17 00:00:00 2001 From: rmoff Date: Wed, 15 Apr 2026 17:52:58 +0100 Subject: [PATCH 1/2] Kafka Connect: Add Trivy CVE scan to CI workflow Add a Trivy vulnerability scan to the Kafka Connect CI workflow that scans bundled JARs for known CVEs with available fixes. The scan runs after the existing check task on JVM 21 only (dependency CVEs are JVM-independent). It builds distZip, unpacks it, and scans using rootfs mode via lhotari/sandboxed-trivy-action (ASF-allowlisted). Behaviour: - Flag, don't block: continue-on-error keeps the job green when CVEs are found. The step shows an orange warning icon in the GitHub UI. - On push to main/release branches: SARIF results are uploaded to the GitHub Security tab for ongoing tracking. - On PRs: SARIF upload is skipped (GitHub only accepts results from default/protected branches). Findings are visible in the CI log. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/kafka-connect-ci.yml | 67 ++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/.github/workflows/kafka-connect-ci.yml b/.github/workflows/kafka-connect-ci.yml index 0919dc6c755a..780a1ca68671 100644 --- a/.github/workflows/kafka-connect-ci.yml +++ b/.github/workflows/kafka-connect-ci.yml @@ -71,6 +71,9 @@ jobs: kafka-connect-tests: runs-on: ubuntu-24.04 + permissions: + contents: read + security-events: write strategy: max-parallel: 15 matrix: @@ -104,3 +107,67 @@ jobs: name: test logs path: | **/build/testlogs + # ------------------------------------------------------------------ + # Trivy CVE scan + # + # Scans bundled jars for known vulnerabilities. + # Only runs on JVM 21 — dependency CVEs are JVM-independent so + # a single scan avoids redundant work. + # + # Behaviour: + # - Flag, don't block: the scan step uses exit-code 1 so it + # "fails" when CVEs are found, but continue-on-error keeps + # the overall job green. GitHub Actions shows the step with + # an orange warning icon. This is the only mechanism Actions + # provides for "visible but non-blocking" — there is no way + # to show a red step while keeping the job green. + # - On push to main/release branches: results are uploaded as + # SARIF to the GitHub Security tab for ongoing tracking. + # - On PRs: SARIF upload is skipped because GitHub's Security + # tab only accepts results from default/protected branches. + # CVE findings are visible in the CI log output instead. + # ------------------------------------------------------------------ + - name: Build Kafka Connect distribution for scanning + if: matrix.jvm == 21 + run: | + ./gradlew -DsparkVersions= -DflinkVersions= -DkafkaVersions=3 \ + :iceberg-kafka-connect:iceberg-kafka-connect-runtime:distZip \ + -Pquick=true -x test -x javadoc + - name: Unpack distribution for scanning + if: matrix.jvm == 21 + run: | + mkdir -p /tmp/kafka-connect-scan + unzip kafka-connect/kafka-connect-runtime/build/distributions/iceberg-kafka-connect-runtime-*.zip \ + -d /tmp/kafka-connect-scan + # Scan and output results as SARIF (for upload on push) while also + # printing a human-readable summary to the CI log. exit-code 1 means + # the step fails when CVEs are found; continue-on-error means the + # job continues and the step shows as orange (not red) in the UI. + - name: Run Trivy vulnerability scan + if: matrix.jvm == 21 + continue-on-error: true + uses: lhotari/sandboxed-trivy-action@f01374b6cc3bf7264ab238293e94f6db7ada6dd0 # v1.0.2 + with: + scan-type: 'rootfs' + scan-ref: '/tmp/kafka-connect-scan' + scanners: 'vuln' + ignore-unfixed: true + exit-code: '1' + format: 'sarif' + output: 'trivy-results.sarif' + # Print human-readable results to the CI log so they're visible + # without downloading the SARIF file. + - name: Print Trivy scan results + if: matrix.jvm == 21 + run: | + if [ -f trivy-results.sarif ]; then + echo "## Trivy CVE Scan Results" + jq -r '.runs[].results[] | "- \(.ruleId): \(.message.text)"' trivy-results.sarif 2>/dev/null || echo "No findings or unable to parse SARIF." + else + echo "No SARIF file found — scan may have failed to install." + fi + - name: Upload Trivy results to GitHub Security tab + if: matrix.jvm == 21 && github.event_name == 'push' + uses: github/codeql-action/upload-sarif@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4 + with: + sarif_file: 'trivy-results.sarif' From d1b2ca2cd5d3a048ac1e1ce01b86dda314f425e7 Mon Sep 17 00:00:00 2001 From: rmoff Date: Fri, 17 Apr 2026 12:14:02 +0100 Subject: [PATCH 2/2] Fail the step if CVE is found (job is non-blocking) --- .github/workflows/kafka-connect-ci.yml | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/.github/workflows/kafka-connect-ci.yml b/.github/workflows/kafka-connect-ci.yml index abe9ffc1b061..d398e9e010a0 100644 --- a/.github/workflows/kafka-connect-ci.yml +++ b/.github/workflows/kafka-connect-ci.yml @@ -114,12 +114,8 @@ jobs: # a single scan avoids redundant work. # # Behaviour: - # - Flag, don't block: the scan step uses exit-code 1 so it - # "fails" when CVEs are found, but continue-on-error keeps - # the overall job green. GitHub Actions shows the step with - # an orange warning icon. This is the only mechanism Actions - # provides for "visible but non-blocking" — there is no way - # to show a red step while keeping the job green. + # - If a CVE is found, the step will fail. However, since this job + # is not a required one, it will not block merging. # - On push to main/release branches: results are uploaded as # SARIF to the GitHub Security tab for ongoing tracking. # - On PRs: SARIF upload is skipped because GitHub's Security @@ -139,12 +135,9 @@ jobs: unzip kafka-connect/kafka-connect-runtime/build/distributions/iceberg-kafka-connect-runtime-*.zip \ -d /tmp/kafka-connect-scan # Scan and output results as SARIF (for upload on push) while also - # printing a human-readable summary to the CI log. exit-code 1 means - # the step fails when CVEs are found; continue-on-error means the - # job continues and the step shows as orange (not red) in the UI. + # printing a human-readable summary to the CI log. - name: Run Trivy vulnerability scan if: matrix.jvm == 21 - continue-on-error: true uses: lhotari/sandboxed-trivy-action@f01374b6cc3bf7264ab238293e94f6db7ada6dd0 # v1.0.2 with: scan-type: 'rootfs' @@ -157,7 +150,7 @@ jobs: # Print human-readable results to the CI log so they're visible # without downloading the SARIF file. - name: Print Trivy scan results - if: matrix.jvm == 21 + if: always() && matrix.jvm == 21 run: | if [ -f trivy-results.sarif ]; then echo "## Trivy CVE Scan Results" @@ -166,7 +159,7 @@ jobs: echo "No SARIF file found — scan may have failed to install." fi - name: Upload Trivy results to GitHub Security tab - if: matrix.jvm == 21 && github.event_name == 'push' + if: always() && matrix.jvm == 21 && github.event_name == 'push' uses: github/codeql-action/upload-sarif@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1 with: sarif_file: 'trivy-results.sarif'