diff --git a/.github/failed-vuln-check.md b/.github/failed-vuln-check.md new file mode 100644 index 00000000..2829e4d4 --- /dev/null +++ b/.github/failed-vuln-check.md @@ -0,0 +1,12 @@ +--- +title: Container Vulnerability Scanner Failed +labels: work-cycle, security +--- +Trivy Vulnerability Scan failed. + +URL: {{ env.WORKFLOW_URL }} +Output: + +``` +{{ env.SCANNER_OUTPUTS }} +``` diff --git a/.github/workflows/build-docker-image.yml b/.github/workflows/build-docker-image.yml index 9793a570..acb99ae9 100644 --- a/.github/workflows/build-docker-image.yml +++ b/.github/workflows/build-docker-image.yml @@ -55,3 +55,70 @@ jobs: tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} file: Dockerfile + container-vuln-scan: + needs: build-and-push-image + runs-on: ubuntu-latest + if: + steps: + - name: Checkout code + uses: actions/checkout@v2 + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=ref,event=pr + type=sha + env: + DOCKER_METADATA_PR_HEAD_SHA: true + - name: Run Trivy vulnerability scanner + uses: aquasecurity/trivy-action@0.20.0 + id: runscanner + continue-on-error: true + with: + image-ref: 'ghcr.io/pulibrary/dpul-collections:${{ steps.meta.outputs.version }}' + format: 'table' + exit-code: '1' + ignore-unfixed: true + vuln-type: 'os,library' + severity: 'CRITICAL,HIGH' + output: 'vulnerabilities.table' + - name: Set variables + id: scanner + if: ${{ always() }} + run: | + EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) + echo "results<<$EOF" >> $GITHUB_OUTPUT + echo "$(cat vulnerabilities.table)" >> $GITHUB_OUTPUT + echo "$EOF" >> $GITHUB_OUTPUT + - name: Output variable + if: ${{ always() }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + SCANNER_OUTPUTS: ${{ steps.scanner.outputs.results }} + run: echo "${{ env.SCANNER_OUTPUTS }}" + - name: Find Comment for scan + if: github.event_name == 'pull_request' + uses: peter-evans/find-comment@v3 + id: fc + with: + issue-number: ${{ github.event.pull_request.number }} + comment-author: 'github-actions[bot]' + body-includes: 'Container Scanning Status: ' + - name: Create or update comment + if: github.event_name == 'pull_request' + uses: peter-evans/create-or-update-comment@v4 + env: + SCANNER_OUTPUTS: ${{ steps.scanner.outputs.results }} + with: + comment-id: ${{ steps.fc.outputs.comment-id }} + issue-number: ${{ github.event.pull_request.number }} + body: | + ## Container Scanning Status: ${{ steps.runscanner.outcome != 'success' && '❌ Failure' || '✅ Success' }} + ``` + ${{ env.SCANNER_OUTPUTS }} + ``` + edit-mode: replace diff --git a/.github/workflows/nightly-vuln-scanning.yml b/.github/workflows/nightly-vuln-scanning.yml new file mode 100644 index 00000000..1a08e8d1 --- /dev/null +++ b/.github/workflows/nightly-vuln-scanning.yml @@ -0,0 +1,71 @@ +name: Run nightly vulnerability check + +on: + push: + branches: + - main + schedule: + - cron: '0 0 * * *' + +# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds. +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu. +jobs: + container-vuln-scan: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + - name: Run Trivy vulnerability scanner + uses: aquasecurity/trivy-action@0.20.0 + id: runscanner + continue-on-error: true + with: + image-ref: 'ghcr.io/pulibrary/dpul-collections:main' + format: 'table' + exit-code: '1' + ignore-unfixed: true + vuln-type: 'os,library' + severity: 'CRITICAL,HIGH' + output: 'vulnerabilities.table' + - name: Set variables + id: scanner + if: job.steps.runscanner.status == failure() + run: | + EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64) + echo "results<<$EOF" >> $GITHUB_OUTPUT + echo "$(cat vulnerabilities.table)" >> $GITHUB_OUTPUT + echo "$EOF" >> $GITHUB_OUTPUT + - name: Output variable + if: job.steps.runscanner.status == failure() + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + SCANNER_OUTPUTS: ${{ steps.scanner.outputs.results }} + run: echo "${{ env.SCANNER_OUTPUTS }}" + - name: Create issue + if: steps.runscanner.outcome != 'success' + uses: JasonEtco/create-an-issue@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + SCANNER_OUTPUTS: ${{ steps.scanner.outputs.results }} + with: + filename: .github/failed-vuln-check.md + update_existing: true + - name: Find existing security issue + id: issues + if: steps.runscanner.outcome == 'success' + uses: lee-dohm/select-matching-issues@v1 + with: + query: 'Container Vulnerability Scanner Failed is:open ' + token: ${{ secrets.GITHUB_TOKEN }} + - name: Close found issues + continue-on-error: true + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + if: steps.runscanner.outcome == 'success' + run: cat ${{ steps.issues.outputs.path }} | xargs gh issue close -c 'Container Scan Passing on Merge to Main' diff --git a/Dockerfile b/Dockerfile index 5b472893..bcee8608 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,8 +12,8 @@ # - Ex: hexpm/elixir:1.16.3-erlang-26.2.5-debian-bullseye-20240513-slim # ARG ELIXIR_VERSION=1.16.3 -ARG OTP_VERSION=26.2.5 -ARG DEBIAN_VERSION=bookworm-20240513-slim +ARG OTP_VERSION=26.2.5.2 +ARG DEBIAN_VERSION=bookworm-20240701-slim ARG BUILDER_IMAGE="hexpm/elixir:${ELIXIR_VERSION}-erlang-${OTP_VERSION}-debian-${DEBIAN_VERSION}" ARG RUNNER_IMAGE="debian:${DEBIAN_VERSION}"