Skip to content

Commit 0ad24b0

Browse files
msukkariclaude
andcommitted
refactor: add normalized id field to all three alert sources
Each source now has a pre-computed `id` field so Claude can deduplicate with simple string matching instead of inferring IDs: - Trivy: extracted into trivy-alerts.json with id = VulnerabilityID - Dependabot: id = cve_id (preferred) or ghsa_id (fallback) - CodeQL: id = "codeql:" + rule_id Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent e95488b commit 0ad24b0

1 file changed

Lines changed: 27 additions & 16 deletions

File tree

.github/workflows/trivy-vulnerability-triage.yml

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -218,11 +218,21 @@ jobs:
218218
with:
219219
name: trivy-results
220220

221-
- name: Ensure Trivy results file exists
221+
- name: Normalize Trivy results
222222
run: |
223223
if [ ! -f trivy-results.json ]; then
224224
echo '{"Results":[]}' > trivy-results.json
225225
fi
226+
jq '[.Results[]? | .Vulnerabilities[]? | {
227+
id: .VulnerabilityID,
228+
severity: .Severity,
229+
pkg_name: .PkgName,
230+
installed_version: .InstalledVersion,
231+
fixed_version: (.FixedVersion // ""),
232+
title: (.Title // ""),
233+
description: (.Description // ""),
234+
references: ([.References[]?] // [])
235+
}]' trivy-results.json > trivy-alerts.json
226236
227237
- name: Fetch Dependabot alerts
228238
env:
@@ -258,6 +268,7 @@ jobs:
258268
fi
259269
260270
EXTRACTED=$(echo "$BODY" | jq '[.[] | {
271+
id: (.security_advisory.cve_id // .security_advisory.ghsa_id // ""),
261272
cve_id: (.security_advisory.cve_id // empty),
262273
ghsa_id: (.security_advisory.ghsa_id // empty),
263274
severity: (.security_advisory.severity // "medium"),
@@ -295,7 +306,7 @@ jobs:
295306
echo "" >> "$GITHUB_STEP_SUMMARY"
296307
echo "| CVE / GHSA | Severity | Package | Ecosystem | Patched Version |" >> "$GITHUB_STEP_SUMMARY"
297308
echo "|------------|----------|---------|-----------|-----------------|" >> "$GITHUB_STEP_SUMMARY"
298-
jq -r '.[] | "| \(.cve_id // .ghsa_id) | \(.severity) | \(.package_name) | \(.package_ecosystem) | \(.first_patched_version // "N/A") |"' dependabot-alerts.json >> "$GITHUB_STEP_SUMMARY"
309+
jq -r '.[] | "| \(.id) | \(.severity) | \(.package_name) | \(.package_ecosystem) | \(.first_patched_version // "N/A") |"' dependabot-alerts.json >> "$GITHUB_STEP_SUMMARY"
299310
fi
300311
fi
301312
@@ -333,6 +344,7 @@ jobs:
333344
fi
334345
335346
EXTRACTED=$(echo "$BODY" | jq '[.[] | {
347+
id: ("codeql:" + (.rule.id // "")),
336348
number: .number,
337349
rule_id: (.rule.id // ""),
338350
rule_description: (.rule.description // ""),
@@ -370,7 +382,7 @@ jobs:
370382
echo "" >> "$GITHUB_STEP_SUMMARY"
371383
echo "| Rule ID | Severity | Tool | File | Lines |" >> "$GITHUB_STEP_SUMMARY"
372384
echo "|---------|----------|------|------|-------|" >> "$GITHUB_STEP_SUMMARY"
373-
jq -r '.[] | "| \(.rule_id) | \(.security_severity_level) | \(.tool_name) | \(.location_path) | \(.location_start_line)-\(.location_end_line) |"' codeql-alerts.json >> "$GITHUB_STEP_SUMMARY"
385+
jq -r '.[] | "| \(.id) | \(.security_severity_level) | \(.tool_name) | \(.location_path) | \(.location_start_line)-\(.location_end_line) |"' codeql-alerts.json >> "$GITHUB_STEP_SUMMARY"
374386
fi
375387
fi
376388
@@ -388,30 +400,29 @@ jobs:
388400
--json-schema '{"type":"object","properties":{"cves":{"type":"array","items":{"type":"object","properties":{"cveId":{"type":"string","description":"CVE ID, GHSA ID, or codeql:<rule-id>"},"severity":{"type":"string","enum":["CRITICAL","HIGH","MEDIUM","LOW"]},"source":{"type":"string","enum":["trivy","dependabot","codeql","trivy+dependabot"],"description":"Which scanner(s) reported this finding"},"title":{"type":"string","description":"Short summary for the Linear issue title"},"description":{"type":"string","description":"Markdown analysis: affected packages, direct vs transitive, remediation steps, and references"},"affectedPackage":{"type":"string"},"linearIssueExists":{"type":"boolean"}},"required":["cveId","severity","source","title","description","affectedPackage","linearIssueExists"]}}},"required":["cves"]}'
389401
prompt: |
390402
You are a security engineer triaging vulnerabilities and security findings for the Sourcebot Docker image.
391-
You have three data sources to analyze:
403+
You have three data sources to analyze. Each is a JSON array where every entry has a pre-computed
404+
`id` field for deterministic deduplication:
392405
393-
1. **Trivy scan results** in `trivy-results.json` — container image vulnerability scan (JSON format with `Results[].Vulnerabilities[]` array)
394-
2. **Dependabot alerts** in `dependabot-alerts.json` — GitHub dependency vulnerability alerts
395-
3. **CodeQL alerts** in `codeql-alerts.json` — GitHub code scanning findings
406+
1. **Trivy scan results** in `trivy-alerts.json` — each entry has `id` (CVE ID, e.g., `CVE-2024-1234`)
407+
2. **Dependabot alerts** in `dependabot-alerts.json` — each entry has `id` (CVE ID or GHSA ID)
408+
3. **CodeQL alerts** in `codeql-alerts.json` — each entry has `id` (prefixed, e.g., `codeql:js/sql-injection`)
396409
397410
## Your Task
398411
399-
1. Read and analyze all three data sources. For **each unique finding**, produce a separate entry
400-
in the `cves` array.
412+
1. Read and analyze all three data sources. For **each unique `id`**, produce a separate entry
413+
in the `cves` array. Use the `id` field as the `cveId`.
401414
402-
2. **Deduplication**: Trivy and Dependabot may report the same CVE. If a CVE ID appears in both
403-
Trivy results and Dependabot alerts, merge them into a single entry with `source: "trivy+dependabot"`.
404-
Combine information from both sources in the description. CodeQL alerts are always unique — they
405-
use rule IDs, not CVE IDs.
415+
2. **Deduplication**: If the same `id` appears in both `trivy-alerts.json` and `dependabot-alerts.json`,
416+
merge them into a single entry with `source: "trivy+dependabot"`. Combine information from both
417+
sources in the description. CodeQL `id` values are prefixed with `codeql:` so they never collide.
406418
407419
3. For **Trivy and Dependabot findings**:
408-
- Use the CVE ID (e.g., `CVE-2024-1234`) as `cveId`. If a Dependabot alert only has a GHSA ID
409-
and no CVE ID, use the GHSA ID (e.g., `GHSA-xxxx-xxxx-xxxx`) as `cveId`.
420+
- Use the `id` field as `cveId`.
410421
- Set `source` to `"trivy"`, `"dependabot"`, or `"trivy+dependabot"` as appropriate.
411422
- Include the affected package, severity, remediation steps, and whether it is direct or transitive.
412423
413424
4. For **CodeQL findings**:
414-
- Use `codeql:<rule_id>` as the `cveId` (e.g., `codeql:js/sql-injection`).
425+
- Use the `id` field as `cveId` (already prefixed with `codeql:`).
415426
- Set `source` to `"codeql"`.
416427
- Include the file location (path and line numbers) and rule description in the `description`.
417428
- Include the alert URL for reference.

0 commit comments

Comments
 (0)