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/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()