Container Security Scan #10
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Copyright AGNTCY Contributors (https://github.com/agntcy) | |
| # SPDX-License-Identifier: Apache-2.0 | |
| name: Container Security Scan | |
| on: | |
| # Nightly scan on main branch only; manual dispatch allowed. | |
| schedule: | |
| - cron: "0 3 * * *" # Daily at 03:00 UTC (runs on default branch context: main) | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| security-events: write # for uploading SARIF | |
| actions: read | |
| issues: write # create issues for critical CVEs | |
| jobs: | |
| get-version: | |
| name: Get Latest Release Version | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.get-release.outputs.version }} | |
| steps: | |
| - name: Get latest release | |
| id: get-release | |
| run: | | |
| LATEST_TAG=$(curl -s https://api.github.com/repos/${{ github.repository }}/releases/latest | jq -r .tag_name) | |
| echo "version=${LATEST_TAG}" >> $GITHUB_OUTPUT | |
| echo "Latest release version: ${LATEST_TAG}" | |
| trivy-scan: | |
| name: Trivy Image Scan (Pull from GHCR) | |
| runs-on: ubuntu-latest | |
| needs: get-version | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - image: scheduler-agent | |
| repo: ghcr.io/${{ github.repository_owner }}/apps/scheduler-agent | |
| version: latest | |
| - image: guide-agent | |
| repo: ghcr.io/${{ github.repository_owner }}/apps/guide-agent | |
| version: latest | |
| - image: tourist-agent | |
| repo: ghcr.io/${{ github.repository_owner }}/apps/tourist-agent | |
| version: latest | |
| - image: ui-agent | |
| repo: ghcr.io/${{ github.repository_owner }}/apps/ui-agent | |
| version: latest | |
| - image: frontend | |
| repo: ghcr.io/${{ github.repository_owner }}/apps/frontend | |
| version: latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 | |
| - name: Log in to GHCR | |
| uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.repository_owner }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Pull image (explicit version) | |
| run: | | |
| set -euo pipefail | |
| IMAGE_REF="${{ matrix.repo }}:${{ matrix.version }}" | |
| echo "Pulling $IMAGE_REF" | |
| docker pull "$IMAGE_REF" | |
| docker image inspect "$IMAGE_REF" >/dev/null 2>&1 | |
| - name: Run Trivy vulnerability scan (image) | |
| uses: aquasecurity/trivy-action@9ab158e8597f3b310480b9a69402b419bc03dbd5 # v0.24.0 | |
| with: | |
| image-ref: ${{ matrix.repo }}:${{ matrix.version }} | |
| format: sarif | |
| output: trivy-${{ matrix.image }}.sarif | |
| vuln-type: "os,library" | |
| severity: "CRITICAL,HIGH,MEDIUM" | |
| ignore-unfixed: true | |
| - name: Upload SARIF | |
| uses: github/codeql-action/upload-sarif@1b1aada464948af03b950897e5eb522f92603cc2 # v3.26.9 | |
| with: | |
| sarif_file: trivy-${{ matrix.image }}.sarif | |
| # Distinguish reports per container image in Code Scanning UI | |
| category: trivy-${{ matrix.image }} | |
| - name: Upload raw report artifact | |
| uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 | |
| with: | |
| name: trivy-report-${{ matrix.image }} | |
| path: trivy-${{ matrix.image }}.sarif | |
| retention-days: 7 | |
| summarize: | |
| name: Summarize Results | |
| needs: [trivy-scan] | |
| runs-on: ubuntu-latest | |
| if: always() | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 | |
| - name: Download artifacts | |
| uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 | |
| with: | |
| path: trivy-artifacts | |
| - name: Debug artifact contents | |
| run: | | |
| echo "Downloaded artifact directory tree:" >> $GITHUB_STEP_SUMMARY | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| find trivy-artifacts -maxdepth 3 -type f -print >> $GITHUB_STEP_SUMMARY || true | |
| echo '```' >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| - name: Generate summary | |
| run: | | |
| chmod +x .github/workflows/scripts/security/generate_trivy_summary.sh | |
| .github/workflows/scripts/security/generate_trivy_summary.sh | |
| - name: Fail if critical vulns found (optional gate) | |
| if: ${{ github.event_name != 'pull_request' }} | |
| run: | | |
| set -e | |
| found=$(grep -R "CRITICAL" -c trivy-artifacts || true) | |
| if [ "${found}" != "0" ]; then | |
| echo "Critical vulnerabilities detected. (Gate currently informational.)" >&2 | |
| fi | |
| - name: Create GitHub issues for critical CVEs | |
| if: ${{ github.event_name != 'pull_request' }} | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| GITHUB_REPOSITORY: ${{ github.repository }} | |
| run: | | |
| set -euo pipefail | |
| echo "Installing dependencies for issue creation script"; | |
| npm init -y >/dev/null 2>&1 || true | |
| npm install @octokit/rest@21 glob >/dev/null 2>&1 | |
| node .github/workflows/scripts/security/create_critical_cve_issues.js |