feat: improve CVE command, version-scan script, and per-branch statement guidance#4038
feat: improve CVE command, version-scan script, and per-branch statement guidance#4038amirbenun merged 7 commits intoelastic:mainfrom
Conversation
|
This pull request does not have a backport label. Could you fix it @amirbenun? 🙏
|
There was a problem hiding this comment.
Pull request overview
Adds automation and guidance to streamline Cloudbeat CVE investigations and generate consistent per-branch security statements, including a ref-scanning helper script and a GitHub Agentic Workflow to post statements to elastic/security issues.
Changes:
- Added
scripts/scan-go-mod-refs.shto scango.moddependency versions acrossmain, maintained minor branches, and tags. - Expanded
llm/cve.mdwith per-branch versioning guidance and an investigation algorithm based on scanning refs and deriving affected/fix versions. - Introduced an agentic workflow definition to generate and post CVE security statements as issue comments in
elastic/security.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
| scripts/scan-go-mod-refs.sh | New scanning script to report dependency versions per ref (main/branches/tags). |
| llm/cve.md | Updated CVE investigation guide with per-branch versioning/derivation workflow and gh-based issue resolution. |
| .github/workflows/cve-statement-comment.md | Added Agentic Workflow to produce and post a CVE statement comment to elastic/security. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| Issue URL: **${{ github.event.inputs.issue_url }}** | ||
|
|
||
| Parse owner, repo, and issue number from this URL. The comment goes to that issue in `elastic/security`. |
There was a problem hiding this comment.
The workflow text instructs to “Parse owner, repo, and issue number” from the input URL, but safe-outputs.add-comment.target-repo is hard-coded to elastic/security. Either validate that the URL’s owner/repo is elastic/security (and fail otherwise) or simplify the instructions to only parse the issue number to avoid ambiguity/mis-posting.
| Parse owner, repo, and issue number from this URL. The comment goes to that issue in `elastic/security`. | |
| Parse the issue number from this URL (the owner and repo are always `elastic/security`). The comment goes to that issue in `elastic/security`. |
scripts/scan-go-mod-refs.sh
Outdated
| echo "Fetching origin..." >&2 | ||
| git fetch origin |
There was a problem hiding this comment.
--fetch runs git fetch origin, but the script relies on tags (git tag -l ...) and remote-tracking branches; git fetch origin does not guarantee all tags are present/up to date. This can silently miss releases and produce incomplete CVE version ranges. Consider fetching tags explicitly (e.g. include tags/pruning) or enumerating tags via git ls-remote --tags origin and then fetching the specific tag objects needed for git show.
| echo "Fetching origin..." >&2 | |
| git fetch origin | |
| echo "Fetching origin (including tags, pruning stale refs)..." >&2 | |
| git fetch --tags --prune origin |
scripts/scan-go-mod-refs.sh
Outdated
| while IFS= read -r tag; do | ||
| [[ -z "$tag" ]] && continue | ||
| REFS+=("$tag") | ||
| done < <(git tag -l "v${minor}.*" 2>/dev/null | sort -V || true) |
There was a problem hiding this comment.
git tag -l "v${minor}.*" reads local tags, but the goal (and docs) are to scan maintained versions on origin. If local tags are stale/missing, the scan output will be incorrect. Prefer listing tags from the remote (or ensuring tags are fetched) so the results reflect upstream state.
| done < <(git tag -l "v${minor}.*" 2>/dev/null | sort -V || true) | |
| done < <(git ls-remote --tags --refs origin "v${minor}.*" 2>/dev/null | awk '{print $2}' | sed 's|^refs/tags/||' | sort -V || true) |
scripts/scan-go-mod-refs.sh
Outdated
| show_ref() { | ||
| local ref="$1" | ||
| local line | ||
| if line=$(git show "$ref":go.mod 2>/dev/null | grep -F "$LIBRARY_NAME"); then |
There was a problem hiding this comment.
grep -F "$LIBRARY_NAME" can match multiple lines (e.g., both require and replace, or indirect + direct) and will then embed newlines into line, producing multi-line output for a single ref. If the intent is a single module version per ref, tighten the match to the actual module column in go.mod (and/or select the first match explicitly) to avoid ambiguous results.
| if line=$(git show "$ref":go.mod 2>/dev/null | grep -F "$LIBRARY_NAME"); then | |
| if line=$(git show "$ref":go.mod 2>/dev/null | awk -v mod="$LIBRARY_NAME" '$1 == mod { print; exit }'); then |
| fi | ||
|
|
||
| # Get maintained minor branches (e.g. 8.19, 9.2, 9.3) | ||
| MINORS=$(curl -sL "https://elastic-release-api.s3.us-west-2.amazonaws.com/public/future-releases.json" | jq -r '.releases[].version' | sort -V | awk -F. '{key=$1"."$2; if(key!=p){if(p) print p; p=key}} END{if(p) print p}') |
There was a problem hiding this comment.
The maintained-minors pipeline uses curl -sL ... | jq ...; without curl -f (or equivalent) an HTTP error can yield confusing jq errors, and missing jq/curl will also fail without a clear message. Consider failing fast on HTTP errors and adding a small dependency check with a clearer stderr message so users know what to install/fix.
|
|
||
| ## Output Format | ||
|
|
||
| When **affected**, the statement (and optionally the YAML) should include **infected Cloudbeat version(s)** and **fix version(s)** (see [Cloudbeat version branches](#cloudbeat-version-branches-affected-infected-and-fix-versions)). |
There was a problem hiding this comment.
The link target #cloudbeat-version-branches-affected-infected-and-fix-versions does not match the actual heading text (### Cloudbeat version branches: affected and fix versions), so this anchor will be broken on GitHub. Update the fragment to match the heading’s generated anchor (e.g. #cloudbeat-version-branches-affected-and-fix-versions).
| When **affected**, the statement (and optionally the YAML) should include **infected Cloudbeat version(s)** and **fix version(s)** (see [Cloudbeat version branches](#cloudbeat-version-branches-affected-infected-and-fix-versions)). | |
| When **affected**, the statement (and optionally the YAML) should include **infected Cloudbeat version(s)** and **fix version(s)** (see [Cloudbeat version branches](#cloudbeat-version-branches-affected-and-fix-versions)). |
|
|
||
| **Algorithm (three steps)** | ||
|
|
||
| 1. **Scan** — Run the script. Use `-f` or `--fetch` to fetch `origin` first; otherwise it uses existing refs. It gets maintained minors from the future-releases API, then prints dependency version (or N/A) for `origin/main`, each maintained branch tip, and every tag `vX.Y.*`. It uses upstream refs only. |
There was a problem hiding this comment.
This section says the script scans origin branch tips and “every tag vX.Y.*” and “uses upstream refs only”, but scripts/scan-go-mod-refs.sh currently enumerates tags from the local repo (git tag -l) and --fetch doesn’t ensure tags are updated. Either adjust the script to truly use remote tags, or update this guidance so investigators don’t assume the output is complete without an explicit tag fetch.
| 1. **Scan** — Run the script. Use `-f` or `--fetch` to fetch `origin` first; otherwise it uses existing refs. It gets maintained minors from the future-releases API, then prints dependency version (or N/A) for `origin/main`, each maintained branch tip, and every tag `vX.Y.*`. It uses upstream refs only. | |
| 1. **Scan** — Run the script. Use `-f` or `--fetch` to fetch `origin` branch refs first; otherwise it uses existing local refs. It gets maintained minors from the future-releases API, then prints dependency version (or N/A) for `origin/main`, each maintained branch tip, and every **local** tag `vX.Y.*`. To ensure tags from `origin` are included, run `git fetch --tags` (or equivalent) before the script. |
Add a script to scan go.mod dependency versions across main and all maintained branches and tags, and updates the CVE investigation guide with branch-per-minor versioning, a scan-classify-derive algorithm for affected and fix versions, and instructions to resolve CVE links via gh. This enables automated, consistent CVE statements and correct per-branch version reporting.