Skip to content

Nightly Vulnerability Scan #265

Nightly Vulnerability Scan

Nightly Vulnerability Scan #265

Workflow file for this run

name: Nightly Vulnerability Scan
on:
schedule:
- cron: "0 2 * * *"
workflow_dispatch:
env:
REGISTRY: ghcr.io/${{ github.repository }}
jobs:
scan:
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: read
packages: read
security-events: write
issues: write
strategy:
matrix:
image:
- chainguard-jdk25
- chainguard-jdk25-musl
- chainguard-jdk26ea
- chainguard-jdk26ea-musl
- chainguard-jdk26valhalla
- chainguard-jdk26valhalla-musl
- distroless-jre25
- distroless-jre25-musl
- distroless-jre26ea
- distroless-jre26ea-musl
- distroless-jre26valhalla
- distroless-jre26valhalla-musl
- ubi9-jdk25
- ubi9-jdk26ea
- ubi9-jdk26valhalla
fail-fast: false
steps:
- name: Login to GHCR
uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Install Trivy
run: |
curl --fail --location --proto '=https' --tlsv1.3 --retry 3 --retry-delay 2 --silent --show-error \
https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sudo sh -s -- -b /usr/local/bin
- name: Scan with Trivy
id: trivy-scan
continue-on-error: true
run: |
trivy image --exit-code 1 --severity HIGH,CRITICAL \
--format json --output trivy-results-${{ matrix.image }}.json \
${{ env.REGISTRY }}:${{ matrix.image }}
- name: Scan with Grype (Anchore)
id: grype-scan
continue-on-error: true
uses: anchore/scan-action@568b89d27fc18c60e56937bff480c91c772cd993 # v7.1.0
with:
image: ${{ env.REGISTRY }}:${{ matrix.image }}
fail-build: false
severity-cutoff: high
- name: Upload Trivy results
if: always()
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: trivy-results-${{ matrix.image }}
path: trivy-results-${{ matrix.image }}.json
retention-days: 30
- name: Create security issue on failure
if: steps.trivy-scan.outcome == 'failure' || steps.grype-scan.outcome == 'failure'
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const image = '${{ matrix.image }}';
const trivyFailed = '${{ steps.trivy-scan.outcome }}' === 'failure';
const grypeFailed = '${{ steps.grype-scan.outcome }}' === 'failure';
const title = `Security vulnerabilities detected in ${image}`;
const body = `## Security Scan Alert 🚨
HIGH or CRITICAL vulnerabilities detected during nightly scan.
**Image:** \`${{ env.REGISTRY }}:${image}\`
**Scan Date:** ${new Date().toISOString()}
**Workflow:** [View Run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
### Scan Results
${trivyFailed ? '- ❌ **Trivy**: HIGH/CRITICAL vulnerabilities found' : '- ✅ **Trivy**: Passed'}
${grypeFailed ? '- ❌ **Grype**: HIGH/CRITICAL vulnerabilities found' : '- ✅ **Grype**: Passed'}
### Next Steps
1. Review scan artifacts in workflow run
2. Update base images or dependencies
3. Rebuild and republish affected images
4. Verify fixes with manual scan
### Artifacts
- Trivy JSON results available in workflow artifacts
- Grype SARIF results available in workflow artifacts
`;
// Check if issue already exists
const issues = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
labels: ['security', 'vulnerability'],
per_page: 100
});
const existingIssue = issues.data.find(issue =>
issue.title.includes(image) && issue.title.includes('Security vulnerabilities')
);
if (existingIssue) {
// Update existing issue
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: existingIssue.number,
body: `### Update: ${new Date().toISOString()}\n\n${body}`
});
console.log(`Updated existing issue #${existingIssue.number}`);
} else {
// Create new issue
const newIssue = await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: title,
body: body,
labels: ['security', 'vulnerability']
});
console.log(`Created new issue #${newIssue.data.number}`);
}
summary:
needs: scan
if: always()
runs-on: ubuntu-latest
steps:
- name: Scan Summary
run: |
echo "## Nightly Vulnerability Scan Complete" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Scanned all 15 container image variants." >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Date**: $(date -u +"%Y-%m-%d %H:%M:%S UTC")" >> $GITHUB_STEP_SUMMARY
echo "**Registry**: ${{ env.REGISTRY }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Review individual scan results in workflow artifacts." >> $GITHUB_STEP_SUMMARY