From 0044b565297f945c47fff4ac3140fdf87f97c12c Mon Sep 17 00:00:00 2001 From: Emanuela Epure <67077116+emanuelaepure10@users.noreply.github.com> Date: Thu, 18 Apr 2024 22:48:39 +0200 Subject: [PATCH] feat: add trivy vulnerability check Trivy vulnerability check is added the GitHub Actions workflows. ING-4183 --- .github/workflows/action.yml | 122 +++++++++++++++++++++++++++++++++++ .github/workflows/check.yml | 17 +++-- .github/workflows/trivy.yml | 44 +++++++++++++ 3 files changed, 174 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/action.yml create mode 100644 .github/workflows/trivy.yml diff --git a/.github/workflows/action.yml b/.github/workflows/action.yml new file mode 100644 index 0000000000..05e76cc4bf --- /dev/null +++ b/.github/workflows/action.yml @@ -0,0 +1,122 @@ +name: Vulnerability scan + +on: + pull_request: + branches: + #- '*' # Trigger on all branches for pull requests + - feat/ING-4183 + workflow_dispatch: + inputs: + image-ref: + description: 'Image to scan (if not specified an fs scan is done)' + required: false + default: '' + junit-test-output: + description: 'Location to write JUnit test report to' + required: false + default: '' + create-test-report: + description: 'If a JUnit test report should be created by the action (otherwise it is assumed the report is handled outside of the action)' + required: false + default: 'false' # Note: Action inputs are always of type string + fail-for: + description: 'Issue types to fail for if they are present (added to JUnit report)' + default: 'CRITICAL' + report-retention-days: + description: 'Number of days to retain the HTML report' + default: '30' + report-tag: + description: 'Custom tag for report file, discern multiple reports created in the same run. By default, the job ID is used' + default: '' + check-image-user: + description: 'If the user of the Docker image should be checked to be non-root' + default: 'true' # Note: Action inputs are always of type string + +jobs: + build: + runs-on: ubuntu-latest + + steps: + # + # Check Docker image user + # + - name: 'Check Docker image user' + uses: 'wetransform/gha-docker-nonroot@master' + if: ${{ inputs.check-image-user == 'true' && inputs.image-ref != '' && (inputs.junit-test-output != '' || inputs.create-test-report) }} + with: + image-ref: ${{ inputs.image-ref }} + fail-for-root: false # Rather use JUnit report + create-junit-output: false + junit-test-output: ${{ inputs.junit-test-output != '' && inputs.junit-test-output || 'trivy.xml' }}-user-check.xml + + # + # Scan for security vulnerabilities + # + - name: 'Scan Docker image for critical vulnerabilities' + uses: 'aquasecurity/trivy-action@0.12.0' + if: ${{ inputs.junit-test-output != '' || inputs.create-test-report }} + with: + image-ref: '${{ inputs.image-ref }}' + scan-type: ${{ inputs.image-ref != '' && 'image' || 'fs' }} + format: 'template' + template: '@/contrib/junit.tpl' + output: ${{ inputs.junit-test-output != '' && inputs.junit-test-output || 'trivy.xml' }} + ignore-unfixed: true + vuln-type: 'os,library' + severity: ${{ inputs.fail-for }} + + - name: 'Determine report file name' + shell: bash + run: | + INPUT_STRING="${{ inputs.report-tag != '' && inputs.report-tag || github.job }}-trivy.html" + VALID_FILENAME=$(echo "$INPUT_STRING" | sed 's/[^A-Za-z0-9_.-]/_/g') + echo "REPORT_FILENAME=$VALID_FILENAME" >> $GITHUB_ENV + + - name: 'Create vulnerability report as HTML' + uses: 'aquasecurity/trivy-action@0.12.0' + with: + image-ref: '${{ inputs.image-ref }}' + scan-type: ${{ inputs.image-ref != '' && 'image' || 'fs' }} + format: 'template' + template: '@/contrib/html.tpl' + output: ${{ env.REPORT_FILENAME }} + + - name: 'Upload vulnerability report' + uses: 'actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32' + if: always() + with: + name: 'Vulnerability report (HTML)' + path: ${{ env.REPORT_FILENAME }} + retention-days: ${{ inputs.report-retention-days }} + + - name: 'Copy vulnerability summary template' + shell: bash + run: | + cp ${GITHUB_ACTION_PATH}/summary.tpl ./trivy-summary.tpl + + - name: 'Create summary on vulnerabilities' + uses: 'aquasecurity/trivy-action@0.12.0' + with: + image-ref: '${{ inputs.image-ref }}' + scan-type: ${{ inputs.image-ref != '' && 'image' || 'fs' }} + format: 'template' + template: '@trivy-summary.tpl' + output: 'trivy.md' + + - name: 'Add to job summary' + shell: bash + run: | + echo "### Vulnerability summary (${{ inputs.image-ref != '' && inputs.image-ref || 'fs' }})" >> $GITHUB_STEP_SUMMARY + cat trivy.md >> $GITHUB_STEP_SUMMARY + + # + # Report on unit tests and critical vulnerabilities + # + - name: 'Publish Test Report' + uses: 'mikepenz/action-junit-report@150e2f992e4fad1379da2056d1d1c279f520e058' + if: ${{ always() && inputs.create-test-report == 'true' }} + with: + report_paths: ${{ inputs.junit-test-output != '' && inputs.junit-test-output || 'trivy.xml' }}* + fail_on_failure: true + annotate_only: true + detailed_summary: true diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 3a3fa086b6..5409079452 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -3,18 +3,17 @@ name: Check on: pull_request: branches: - - '*' # Trigger on all branches for pull requests + - "*" # Trigger on all branches for pull requests # also run workflow to refresh cache workflow_dispatch: {} schedule: # roughly every 6 days - - cron: '0 0 2,6,10,16,22,28 * *' - + - cron: "0 0 2,6,10,16,22,28 * *" # env: - # instead of embedded Maven use local Maven CLI - # HALE_BUILD_MAVEN_EMBEDDED: 'false' +# instead of embedded Maven use local Maven CLI +# HALE_BUILD_MAVEN_EMBEDDED: 'false' jobs: check: @@ -35,7 +34,7 @@ jobs: - name: Test run: ./build.sh commitStage working-directory: ./build - + - name: Publish Test Report uses: mikepenz/action-junit-report@9379f0ccddcab154835d4e2487555ee79614fe95 # v4.2.1 if: always() # always run even if the previous step fails @@ -47,8 +46,8 @@ jobs: # to the wrong workflow/run. Instead no additional check is created. # See https://github.com/mikepenz/action-junit-report/issues/40 annotate_only: true - detailed_summary: true - report_paths: 'build/target/testReports/*.xml' + detailed_summary: true + report_paths: "build/target/testReports/*.xml" # TODO archive logs? - # build/target/testReports/*.out,build/target/testReports/*.err \ No newline at end of file + # build/target/testReports/*.out,build/target/testReports/*.err diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml new file mode 100644 index 0000000000..2b6f45156b --- /dev/null +++ b/.github/workflows/trivy.yml @@ -0,0 +1,44 @@ +name: 'Scan CI Pipeline (w/ Trivy Config)' + +on: + pull_request: + branches: + - '*' + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Maven + uses: s4u/setup-maven-action@v1.5.1 + with: + java-version: 17 + java-distribution: temurin + maven-version: 3.8.6 + + - name: Run Trivy vulnerability scanner in fs mode + uses: aquasecurity/trivy-action@master + with: + scan-type: 'fs' + scan-ref: '.' + # trivy-config: trivy.yaml + + # Upload Trivy scan results to GitHub Security tab + #- name: Upload Trivy scan results to GitHub Security tab + # uses: github/codeql-action/upload-sarif@v2 + # with: + # sarif_file: 'trivy-scan-results.sarif' + + - name: Upload Trivy scan results + uses: actions/upload-artifact@v2 + with: + name: trivy-results + path: trivy-results.json + + - name: Display Trivy results + run: cat trivy-results.json + if: success() && always()