name: Docker Security Scan on: push: branches: ["main"] paths: - "Dockerfile" - ".github/workflows/docker-security-scan.yml" - "mix.exs" - "mix.lock" pull_request: branches: ["main"] paths: - "Dockerfile" - ".github/workflows/docker-security-scan.yml" - "mix.exs" - "mix.lock" schedule: - cron: "0 0 * * 0" # Run weekly on Sundays at midnight workflow_dispatch: # Allow manual triggers # Cancel in-progress runs when a new workflow with the same group is triggered concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: scan: name: Security Scan runs-on: ubuntu-latest permissions: contents: read security-events: write actions: read packages: read steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build Docker image uses: docker/build-push-action@v5 with: context: . tags: aprsme:${{ github.sha }} load: true cache-from: type=gha cache-to: type=gha,mode=max - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@master with: image-ref: aprsme:${{ github.sha }} format: "sarif" output: "trivy-results.sarif" severity: "CRITICAL,HIGH" timeout: "10m" scanners: "vuln,config,secret" - name: Upload Trivy scan results to GitHub Security tab uses: github/codeql-action/upload-sarif@v3 if: always() with: sarif_file: "trivy-results.sarif" category: "Trivy Scan" - name: Run Trivy for outdated OS packages uses: aquasecurity/trivy-action@master with: image-ref: aprsme:${{ github.sha }} format: "table" output: "os-packages.txt" severity: "HIGH,CRITICAL" vuln-type: "os" - name: Run Trivy for outdated application dependencies uses: aquasecurity/trivy-action@master with: image-ref: aprsme:${{ github.sha }} format: "table" output: "app-packages.txt" severity: "HIGH,CRITICAL" vuln-type: "library" - name: Upload detailed vulnerability reports uses: actions/upload-artifact@v4 if: always() with: name: vulnerability-reports path: | os-packages.txt app-packages.txt retention-days: 7 - name: Run Docker Scout vulnerability scan uses: docker/scout-action@v1 continue-on-error: true with: command: cves image: aprsme:${{ github.sha }} format: sarif only-severities: critical,high sarif-file: scout-results.sarif dockerhub-user: ${{ secrets.DOCKERHUB_USERNAME }} dockerhub-password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Upload Docker Scout results uses: actions/upload-artifact@v4 if: always() with: name: docker-scout-report path: scout-results.sarif if-no-files-found: ignore retention-days: 7 - name: Generate security report summary if: always() run: | echo "# Docker Image Security Report" > security-summary.md echo "## Image: aprsme:${{ github.sha }}" >> security-summary.md echo "## Date: $(date)" >> security-summary.md echo "### OS Package Vulnerabilities" >> security-summary.md echo '```' >> security-summary.md cat os-packages.txt >> security-summary.md || echo "No OS package vulnerabilities report available" >> security-summary.md echo '```' >> security-summary.md echo "### Application Dependencies Vulnerabilities" >> security-summary.md echo '```' >> security-summary.md cat app-packages.txt >> security-summary.md || echo "No application vulnerabilities report available" >> security-summary.md echo '```' >> security-summary.md # Also output to GitHub Actions summary cat security-summary.md >> $GITHUB_STEP_SUMMARY - name: Upload security summary uses: actions/upload-artifact@v4 if: always() with: name: security-summary path: security-summary.md retention-days: 14 - name: Check for critical vulnerabilities continue-on-error: true run: | if grep -q "CRITICAL" trivy-results.sarif; then echo "::warning::Critical vulnerabilities found in the Docker image." echo "Please review the scan results in the Security tab and the uploaded reports." echo "" echo "Summary of critical vulnerabilities:" grep -A 5 -B 5 "CRITICAL" trivy-results.sarif | head -50 || true echo "" echo "For full details, check the Security tab and artifact reports." # Exit with error code but continue-on-error will prevent workflow failure exit 1 else echo "No critical vulnerabilities found." fi