diff --git a/.github/workflows/kafka-connect-ci.yml b/.github/workflows/kafka-connect-ci.yml index 0919dc6c755a..62ffe4d7e8a0 100644 --- a/.github/workflows/kafka-connect-ci.yml +++ b/.github/workflows/kafka-connect-ci.yml @@ -25,6 +25,7 @@ on: - '0.*' - '1.*' - '2.*' + - 'trivy-test-*' # temporary: testing push-event behaviour on fork tags: - 'apache-iceberg-**' pull_request: @@ -71,6 +72,9 @@ jobs: kafka-connect-tests: runs-on: ubuntu-24.04 + permissions: + contents: read + security-events: write strategy: max-parallel: 15 matrix: @@ -104,3 +108,71 @@ jobs: name: test logs path: | **/build/testlogs + # ------------------------------------------------------------------ + # Trivy CVE scan + # + # Scans bundled jars for CRITICAL/HIGH 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: a second scan generates + # SARIF output which is uploaded 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 print results to 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: aquasecurity/trivy-action@e368e328979b113139d6f9068e03accaed98a518 # v0.34.1 + with: + scan-type: 'fs' + scan-ref: '/tmp/kafka-connect-scan' + scanners: 'vuln' + severity: 'CRITICAL,HIGH' + ignore-unfixed: true + exit-code: '1' + # Generate SARIF for the GitHub Security tab (push only). + # No exit-code set (defaults to 0, always succeeds) because this + # step only needs to produce the file — pass/fail signalling is + # handled by the scan step above. No continue-on-error needed + # either, since this step never fails. + - name: Run Trivy vulnerability scan (SARIF) + if: matrix.jvm == 21 && github.event_name == 'push' + uses: aquasecurity/trivy-action@e368e328979b113139d6f9068e03accaed98a518 # v0.34.1 + with: + scan-type: 'fs' + scan-ref: '/tmp/kafka-connect-scan' + scanners: 'vuln' + format: 'sarif' + output: 'trivy-results.sarif' + severity: 'CRITICAL,HIGH' + ignore-unfixed: true + - name: Upload Trivy results to GitHub Security tab + if: matrix.jvm == 21 && github.event_name == 'push' + uses: github/codeql-action/upload-sarif@c4a7bc332abaec03596ff2803dd7f3ca3a238975 # v3 + with: + sarif_file: 'trivy-results.sarif'