From openstack-k8s-agent-tools
Validates CVE Jira tickets against the current Go operator codebase — assesses reachability, exploitability, and recommends action (Go bump, dependency bump, or code fix).
How this skill is triggered — by the user, by Claude, or both
Slash command
/openstack-k8s-agent-tools:cve-validate <OSPRH-ticket-id><OSPRH-ticket-id>This skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Validate whether a reported CVE Jira ticket actually affects the current operator codebase, assess how the affected code is used, and recommend the appropriate action.
Validate whether a reported CVE Jira ticket actually affects the current operator codebase, assess how the affected code is used, and recommend the appropriate action.
When invoked (/cve-validate OSPRH-28972), run the full workflow below and produce a structured report.
You must run this skill from within the operator repository that the CVE is filed against. The skill analyzes the code in the current working directory — if you are in the wrong repo, the results will be meaningless.
Before invoking, ensure:
cd into the operator repo that matches the pscomponent: label on the CVE ticket (e.g., osp-director-operator, glance-operator).v1.3.x, or main). The Go version and dependency versions vary between branches, so the assessment depends on which branch you are on.git pull or git fetch to ensure you are analyzing current code, not a stale checkout.go.mod file.Before starting the workflow, verify the environment:
# Confirm go.mod exists
test -f go.mod || echo "ERROR: no go.mod — are you in the right directory?"
# Show current repo and branch
git remote get-url origin
git branch --show-current
head -3 go.mod
Report the repository name, current branch, and Go version to the user at the top of the output so they can confirm they are analyzing the right target:
Analyzing: github.com/openstack-k8s-operators/osp-director-operator
Branch: v1.3.x
Go: 1.24.4
If go.mod is missing, stop and ask the user to navigate to the correct directory.
Use Jira MCP (jira_get_issue) to fetch the ticket with fields: *all.
Extract:
labels field — look for labels matching CVE-*pscomponent:*flaw:bz#* or flawuuid:*From the description, identify the affected Go package or module (e.g., crypto/x509, golang.org/x/net/http2, github.com/golang-jwt/jwt/v5).
If the ticket is not a Vulnerability type or has no CVE label, stop and report:
This ticket is not a CVE vulnerability tracker. Type: <actual type>, Labels: <labels>
Determine whether the CVE affects:
crypto/tls, net/http, encoding/xml). Fix comes with a Go toolchain bump.go.mod under require. Fix requires bumping the dependency version.go.mod directly but pulled in via another dependency. Check go.sum or run grep in go.mod for indirect dependencies.go.mod or go.sum at all. The CVE does not apply.For Go stdlib CVEs, read the go directive from go.mod to get the current Go version.
For dependency CVEs, find the current version from go.mod:
grep '<module-path>' go.mod
Use WebSearch to search for the CVE ID. Gather:
Compare the fix version against the current version from Step 2.
If the current version already includes the fix, stop and report:
CVE-YYYY-NNNNN is already fixed in the current version (<current>) which is >= fix version (<fix>).
No action required.
A single repository can produce multiple container images, each built from different source directories. The CVE ticket's pscomponent: label refers to a specific image, but all images built from this repo share the same go.mod and must all be checked.
Discover all build targets:
# Find all Dockerfiles (excluding CI tooling and .git)
find . -name 'Dockerfile*' -not -path '*/CI_TOOLS_REPO/*' -not -path '*/.git/*'
For each Dockerfile found, identify:
go build commands and their target path (e.g., go build -o manager main.go, go build -o agent ./containers/agent).qemu-img). Skip non-Go images.Report all discovered build targets in the output. Example for a repo that builds multiple images:
### Build Targets
| Image | Dockerfile | Go Source | Go Code? |
|-------|-----------|-----------|----------|
| <operator-name> | Dockerfile | main.go | Yes |
| <operator-name>-agent | Dockerfile.agent | ./containers/agent | Yes |
| <operator-name>-downloader | containers/image_downloader/Dockerfile | N/A (shell script) | No |
Many repos build only a single image (one Dockerfile, one main.go). That is fine — just list the single target. The point is to discover and report all of them.
All subsequent steps (searching for imports, analyzing usage) must cover every Go build target, not just the top-level operator code. Scan the entire repo's Go source (all directories), but report findings grouped by build target so it is clear which image is or is not affected.
Search for imports of the affected package across the entire repository (all build targets):
grep -rn '<package-path>' --include='*.go' . | grep -v vendor/ | grep -v '_test.go'
Also search test files separately (lower risk but worth noting):
grep -rn '<package-path>' --include='*.go' . | grep -v vendor/ | grep '_test.go'
Group findings by build target (e.g., "operator: main.go:22", "agent: containers/agent/main.go:5").
For non-stdlib packages, check whether the affected module appears anywhere in the dependency graph, even if not imported directly by operator code:
go mod graph 2>/dev/null | grep '<module-path>'
If go mod graph is not available (no Go toolchain), fall back to checking go.sum:
grep '<module-path>' go.sum
This reveals transitive dependencies that pull in the vulnerable module. Record which direct dependency pulls it in — this matters for determining the upgrade path.
For Go stdlib packages (crypto/tls, net/http, encoding/xml, etc.), the dependency graph check does not apply since stdlib packages are part of the Go toolchain. Instead, consider which framework dependencies are known to use the affected stdlib package and how:
crypto/tls — used by controller-runtime (webhook server, metrics server), client-go (API server connections), any HTTP client/server in dependenciesnet/http — used by virtually every dependency that makes or serves HTTP requestsencoding/xml — used by specific XML-processing librariesFor each known transitive usage, assess whether the framework's usage pattern matches the vulnerable code path. For example, client-go uses crypto/tls as a TLS client connecting to the API server — this is a different code path than a TLS server verifying client certificates.
For each file that uses the affected package, read the relevant code and assess. Do this for every build target that has Go code, not just the main operator.
Map the actual usage to the CVE's vulnerable function or behavior. For example:
x509.Certificate.Verify is vulnerable — does the code call Verify? Or just MarshalPKCS1PrivateKey?http2 framing is vulnerable — does the code serve HTTP/2? Or only HTTP/1.1?If the specific vulnerable function/pattern is not used, the code is not on the vulnerable path.
Assess the attack surface:
The key question: can an external actor supply the specific input that triggers the vulnerability?
The report must be formatted in markdown so it can be copy/pasted directly into a Jira Cloud comment. Jira Cloud's rich text editor accepts markdown paste and renders headings, tables, bold, links, and code spans.
[AI-GENERATED] prefix as required by project conventions.##, ###), markdown tables, **bold**, `code`, and [text](url) links.```markdown ... ```) so the user can copy the whole block at once.After printing the report, ask the user if they want the report written to a local file for easier copy/paste into Jira (avoids trailing spaces from terminal output). Suggest a filename like /tmp/cve-<CVE-ID>-<ticket>.md (e.g., /tmp/cve-2026-32280-OSPRH-28972.md). If the user confirms, write the markdown content (without the surrounding fenced code block delimiters) to that file.
Output the following structured report:
```markdown
[AI-GENERATED] CVE Validation Report
## CVE Validation Report
| Field | Value |
|-------|-------|
| Ticket | <OSPRH-XXXXX> |
| CVE | <CVE-YYYY-NNNNN> |
| Summary | <one-line from Jira> |
| Component | <pscomponent label value> |
| Repository | <module path from go.mod> |
| Branch | <current branch> |
### Vulnerability Description
<2-3 sentence plain-language description of the CVE. Explain what the flaw is, NOT just which package it is in.>
**How an attacker exploits this:** <Concrete description of the attack vector. What does the attacker send, to what endpoint, and what happens? e.g., "An attacker sends a TLS ClientHello that triggers certificate chain verification against a pool containing thousands of crafted intermediate certificates. The verification algorithm has exponential complexity in the number of candidate parents, causing the server to consume excessive CPU and become unresponsive.">
**Impact:** <DoS / RCE / information disclosure / privilege escalation / etc.>
### Affected Package
| Field | Value |
|-------|-------|
| Package | `<e.g., crypto/x509>` |
| Type | Go stdlib / Direct dependency / Transitive dependency |
| Current version | <Go version or dependency version from go.mod> |
| Fix version | <version that patches the CVE, from web search> |
| Fix included in current version | Yes / No — <"Current version X.Y.Z >= fix version A.B.C" or "Current version X.Y.Z < fix version A.B.C"> |
### Build Targets
| Image | Dockerfile | Go Source | Go Code? |
|-------|-----------|-----------|----------|
| <image-name> | <Dockerfile path> | <Go build target> | Yes/No |
<Include all images built from this repo. Non-Go images can be noted but skipped for code analysis.>
### Codebase Usage
<Group findings by build target.>
| Build Target | File | Line | Function/Usage | Vulnerable Path? |
|-------------|------|------|----------------|-------------------|
| operator | main.go | 22 | tls.Config for webhook server | No -- server-side TLS, no client cert verification |
| pkg/common/ssh.go | 48 | x509.MarshalPKCS1PrivateKey | No -- key marshaling, not chain verification |
If no direct usage found:
> The operator does not import `<package>` directly. The package is used
> transitively by <framework/dependency>. Transitive usage is <assessment>.
### Dependency Graph
<If relevant, show which dependencies pull in the affected module and whether their usage is on a vulnerable path. For stdlib CVEs, note which framework components use the stdlib package and how.>
### Risk Assessment
| Criterion | Assessment |
|-----------|------------|
| Reachable | Yes/No -- <how the affected code path can be reached> |
| Attack surface | <who can reach it: cluster-internal only, external users, requires cluster admin> |
| Exploitability | <how likely given the specific usage pattern> |
| Priority | Not Affected / Low / Medium / High / Critical |
```
Priority guidelines (do not include these in the output — use them to determine the priority):
x509.MarshalPKCS1PrivateKey when the CVE is about x509.Certificate.Verify). Close the ticket as not affected.Continue the report inside the same markdown code block:
```markdown
### Verdict
**<ONE OF THE VERDICTS BELOW>**
<1-2 sentence justification summarizing why this verdict was chosen.>
<If NOT AFFECTED, include the following line. Omit for AFFECTED verdicts.>
**Jira action:** Close as "notabug". Set VEX Justification to "Vulnerable code not in execute path".
### Sources
- [CVE entry](<NVD or Go vuln DB URL>)
- [Fix commit/release](<URL>)
- [Bugzilla](<URL if available>)
```
Use one of these verdicts:
NOT AFFECTED -- close the ticket as "notabug". The operator does not use the vulnerable code path. The package may be imported but the specific vulnerable function/pattern is not called, or the code is not reachable in a way that triggers the vulnerability. No action is needed -- not even waiting for a Go bump. When closing, set the VEX Justification field to "Vulnerable code not in execute path". Include this instruction in the verdict section of the report so the person closing the ticket knows what to set.
AFFECTED -- will be fixed by Go toolchain bump to . The vulnerable code path IS used (directly or transitively in a reachable way), but no code change is needed in this repo. The fix will come when the container image is rebuilt with Go >= .
AFFECTED -- dependency bump required. Bump <module> to >= <version> in go.mod. Check if dependabot is pinned below the fix version.
AFFECTED -- code change required. The vulnerable pattern is used and must be refactored. Describe specifically what needs to change.
Important distinction: "The package is imported" is NOT the same as "the vulnerable code path is used." If the operator imports crypto/x509 but only uses MarshalPKCS1PrivateKey, and the CVE is about Certificate.Verify, the verdict is NOT AFFECTED. Do not recommend waiting for a Go bump when the code is not affected — that creates unnecessary tracking overhead.
If the user provides multiple ticket IDs (/cve-validate OSPRH-28972 OSPRH-29001), process each one sequentially and produce a separate report for each. Add a summary table at the end:
## Summary
| Ticket | CVE | Package | Verdict | Action |
|--------|-----|---------|---------|--------|
| OSPRH-28972 | CVE-2026-32280 | crypto/x509 | Not Affected | Close ticket |
| OSPRH-29001 | CVE-2026-XXXXX | ... | ... | ... |
/cve-validate OSPRH-28972
Expected: crypto/x509 is imported but only for MarshalPKCS1PrivateKey (key marshaling). The CVE is about Certificate.Verify with large intermediates pools — that function is never called. Webhook TLS is server-side only, no client cert verification. Verdict: NOT AFFECTED — close the ticket.
/cve-validate OSPRH-XXXXX
If the CVE affects e.g., net/http request smuggling and the operator runs an HTTP server that parses external requests using the vulnerable pattern, the vulnerable code path is reachable. Verdict: AFFECTED — will be fixed by Go toolchain bump.
/cve-validate OSPRH-XXXXX
If the CVE affects e.g., golang.org/x/crypto and the operator imports and uses the specific vulnerable sub-package/function, check the current pinned version and recommend bumping. Verdict: AFFECTED — dependency bump required.
npx claudepluginhub openstack-k8s-operators/devskills --plugin openstack-k8s-agent-toolsGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.