Skip to content

Commit 2ed7470

Browse files
authored
feat: add daily container rescan workflow (#764)
Add a scheduled Trivy vulnerability scan of the published Docker Hub image (netboxlabs/pktvisor:latest-develop). Renders a vulnerability table in the step summary and uploads SARIF to GitHub Code Scanning. PR-time build scanning is deferred due to the expensive C++ build process. This rescan catches newly disclosed CVEs in the published image.
1 parent f4afa52 commit 2ed7470

1 file changed

Lines changed: 68 additions & 0 deletions

File tree

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
name: Scheduled Container Rescan
2+
3+
on:
4+
schedule:
5+
- cron: '0 6 * * *'
6+
workflow_dispatch:
7+
8+
jobs:
9+
rescan:
10+
name: Rescan Container Image
11+
runs-on: ubuntu-latest
12+
timeout-minutes: 15
13+
permissions:
14+
actions: read
15+
contents: read
16+
security-events: write
17+
env:
18+
TRIVY_DISABLE_VEX_NOTICE: "true"
19+
IMAGE_REF: docker.io/netboxlabs/pktvisor:latest-develop
20+
21+
steps:
22+
- name: Pull image
23+
run: docker pull "$IMAGE_REF"
24+
25+
- name: Scan for vulnerabilities
26+
uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0
27+
with:
28+
image-ref: ${{ env.IMAGE_REF }}
29+
format: json
30+
output: trivy-output.json
31+
vuln-type: os,library
32+
scanners: vuln,secret
33+
severity: CRITICAL,HIGH,MEDIUM,LOW
34+
ignore-unfixed: true
35+
exit-code: "0"
36+
37+
- name: Build rescan summary
38+
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
39+
with:
40+
script: |
41+
const fs = require('fs');
42+
const data = JSON.parse(fs.readFileSync('trivy-output.json', 'utf8'));
43+
const vulns = (data.Results || []).flatMap(r =>
44+
(r.Vulnerabilities || []).map(v => ({ ...v, target: r.Target }))
45+
);
46+
const SEVERITY_LABEL = { CRITICAL: '🔴 **CRITICAL**', HIGH: '🟠 **HIGH**', MEDIUM: '🟡 MEDIUM', LOW: '⚪ LOW' };
47+
let summary = `### Rescan Complete\n\n**Image:** \`${process.env.IMAGE_REF}\`\n**Scanned at:** ${new Date().toISOString().replace('T', ' ').split('.')[0]} UTC\n\n`;
48+
if (vulns.length === 0) {
49+
summary += '_No vulnerabilities found._\n';
50+
} else {
51+
summary += '| Library | CVE | Severity | Installed | Fixed | Title |\n|---|---|---|---|---|---|\n';
52+
for (const v of vulns) {
53+
const title = (v.Title || '').replace(/\|/g, '\\|').substring(0, 80);
54+
const cve = v.PrimaryURL ? `[${v.VulnerabilityID}](${v.PrimaryURL})` : v.VulnerabilityID;
55+
summary += `| ${v.PkgName} | ${cve} | ${SEVERITY_LABEL[v.Severity] || v.Severity} | ${v.InstalledVersion} | ${v.FixedVersion || 'N/A'} | ${title} |\n`;
56+
}
57+
}
58+
fs.appendFileSync(process.env.GITHUB_STEP_SUMMARY, summary);
59+
60+
- name: Convert scan results to SARIF
61+
if: "!cancelled()"
62+
run: trivy convert --format sarif --output trivy-results.sarif trivy-output.json
63+
64+
- name: Upload SARIF to GitHub Code Scanning
65+
if: "!cancelled()"
66+
uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6
67+
with:
68+
sarif_file: trivy-results.sarif

0 commit comments

Comments
 (0)