Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
209 changes: 209 additions & 0 deletions support/redhat-support/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
---
name: redhat-support
description: Query Red Hat security data — look up CVEs, check which Red Hat products are affected by a vulnerability, and find the advisory (RHSA) that fixes a given CVE. Use when validating a CVE ID, assessing whether a CVE affects a specific Red Hat product or package, or correlating a CVE with the Red Hat advisory that resolves it.
---

# Red Hat Security Data

Query the Red Hat Security Data API to retrieve CVE details, affected-product state, and the advisories (RHSAs) that address each CVE. This is the source of record for validating that a CVE ID exists and for understanding how Red Hat has classified and addressed it.

## API Overview

- **Base URL**: `https://access.redhat.com/hydra/rest/securitydata`
- **Authentication**: None required — the endpoints used here are public.
- **Two shapes**:
- **Single CVE detail**: `GET /cve/<CVE-ID>.json`
- **CVE search**: `GET /cve.json` with filter parameters (`package`, `advisory`, `severity`, `after`, `before`, `cwe`, `per_page`)

The single-CVE endpoint returns the full vulnerability record (severity, CVSS, affected products, fix state, references). The search endpoint returns a compact list — use it to enumerate, then drill into individual CVEs with the single-detail endpoint when needed.

## Quick Start

```bash
# Single CVE lookup
curl -s "https://access.redhat.com/hydra/rest/securitydata/cve/CVE-2024-3094.json" | jq .

# Find CVEs affecting a package
curl -s "https://access.redhat.com/hydra/rest/securitydata/cve.json?package=openssh&per_page=10" | jq .

# Find CVEs included in a specific advisory
curl -s "https://access.redhat.com/hydra/rest/securitydata/cve.json?advisory=RHSA-2024:1614&per_page=20" | jq '.[].CVE'
```

## Response Structure

### Single CVE detail (`/cve/<CVE-ID>.json`)

```json
{
"threat_severity": "Critical",
"public_date": "2024-03-29T00:00:00Z",
"bugzilla": { "id": "2272210", "url": "...", "description": "..." },
"cvss3": {
"cvss3_base_score": "10.0",
"cvss3_scoring_vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H",
"status": "draft"
},
"cwe": "CWE-506",
"details": ["..."],
"statement": "...",
"package_state": [
{
"product_name": "Red Hat Enterprise Linux 9",
"package_name": "xz",
"fix_state": "Not affected",
"cpe": "cpe:/o:redhat:enterprise_linux:9"
}
],
"affected_release": [
{
"product_name": "Red Hat Enterprise Linux 8",
"release_date": "2024-04-02T00:00:00Z",
"advisory": "RHSA-2024:1718",
"cpe": "cpe:/o:redhat:enterprise_linux:8",
"package": "openssh-0:8.0p1-19.el8_9"
}
],
"references": ["..."]
}
```

The key fields for agent reasoning:

- `threat_severity` — Red Hat's classification (`Critical`, `Important`, `Moderate`, `Low`)
- `package_state[]` — per-product status when there is **no released fix yet** (`Affected`, `Not affected`, `Will not fix`, `Under investigation`, `Out of support scope`)
- `affected_release[]` — per-product fix metadata when an advisory **has shipped** (includes the `advisory` ID and the fixed `package` NVR)
- `references[]` — links to NVD, CVE.org, blog posts, and KB articles

A given product appears in either `package_state` *or* `affected_release` for a given CVE — not both. If a product is in `affected_release`, the CVE is fixed there.

### CVE search list (`/cve.json`)

Each entry is a compact summary:

```json
{
"CVE": "CVE-2026-35414",
"severity": "moderate",
"public_date": "2026-04-02T17:08:15Z",
"advisories": ["RHSA-2026:16059", "RHSA-2026:13383"],
"bugzilla": "2454490",
"bugzilla_description": "...",
"cvss3_score": "4.8",
"cvss3_scoring_vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N",
"CWE": "CWE-168",
"affected_packages": ["openssh-0:9.9p1-14.el10_1", "..."],
"resource_url": "https://access.redhat.com/hydra/rest/securitydata/cve/CVE-2026-35414.json"
}
```

`resource_url` is the single-CVE-detail endpoint for that entry — follow it for full data.

For full field descriptions, supported filter parameters, and pagination rules, see `references/security-data-api.md`.

## Common Queries

### Validate that a CVE ID exists and is real

```bash
CVE="CVE-2024-3094"
curl -fsS "https://access.redhat.com/hydra/rest/securitydata/cve/$CVE.json" \
> /dev/null && echo "valid" || echo "not found"
```

A 404 here means Red Hat has no record of the CVE — treat it as not a real Red Hat-tracked CVE. (NVD may still have it; this endpoint reflects Red Hat's view only.)

### Get severity, CVSS, and one-line description for a CVE

```bash
CVE="CVE-2024-3094"
curl -s "https://access.redhat.com/hydra/rest/securitydata/cve/$CVE.json" \
| jq -r '
"Severity: \(.threat_severity)",
"CVSS3: \(.cvss3.cvss3_base_score) (\(.cvss3.cvss3_scoring_vector))",
"Bugzilla: \(.bugzilla.description)"'
```

### Check whether a CVE affects a specific Red Hat product

```bash
CVE="CVE-2024-3094"
PRODUCT="Red Hat Enterprise Linux 9"

curl -s "https://access.redhat.com/hydra/rest/securitydata/cve/$CVE.json" \
| jq -r --arg p "$PRODUCT" '
(.package_state // []) as $ps |
(.affected_release // []) as $ar |
([$ps[] | select(.product_name == $p)] + [$ar[] | select(.product_name == $p)]) as $hits |
if ($hits | length) == 0 then "\($p): not listed for this CVE"
else $hits[] |
if .advisory then "\($p): fixed in \(.advisory) (\(.package))"
else "\($p): \(.fix_state) (package: \(.package_name))"
end
end'
```

### Find the Red Hat advisory (RHSA) that fixes a CVE for a given product

```bash
CVE="CVE-2024-1086"
PRODUCT="Red Hat Enterprise Linux 9"

# Exact match — RHEL 9 proper only, excludes EUS / E4S / AUS variants
curl -s "https://access.redhat.com/hydra/rest/securitydata/cve/$CVE.json" \
| jq -r --arg p "$PRODUCT" '
[(.affected_release // [])[] | select(.product_name == $p)] | unique_by(.advisory)[] |
"\(.product_name): \(.advisory) (\(.release_date[:10]))"'
```

A single `(product_name, advisory)` pair can appear multiple times in `affected_release` (typically one per architecture or sub-package); `unique_by(.advisory)` collapses these.

To include EUS / Extended Update Support / Advanced Update Support variants too, broaden the filter:

```bash
# Family match — includes RHEL 9 proper AND its EUS/AUS/E4S variants
curl -s "https://access.redhat.com/hydra/rest/securitydata/cve/$CVE.json" \
| jq -r --arg p "$PRODUCT" '
[(.affected_release // [])[] | select(.product_name | startswith($p))] | unique_by([.product_name, .advisory])[] |
"\(.product_name): \(.advisory) (\(.release_date[:10]))"'
```

Be explicit about which one the user wants — `startswith` will match `"Red Hat Enterprise Linux 9.0 Extended Update Support"`, `"...9.2 Extended Update Support"`, etc., not just RHEL 9 proper.

### List recent CVEs affecting a package

```bash
PACKAGE="openssh"
curl -s "https://access.redhat.com/hydra/rest/securitydata/cve.json?package=$PACKAGE&per_page=20" \
| jq -r '.[] | "\(.CVE) \(.severity) \(.public_date[:10]) — \(.bugzilla_description)"'
```

### List all CVEs included in an advisory

```bash
ADVISORY="RHSA-2024:1614"
curl -s "https://access.redhat.com/hydra/rest/securitydata/cve.json?advisory=$ADVISORY&per_page=100" \
| jq -r '.[].CVE'
```

### Filter by severity and date

```bash
# Critical CVEs disclosed since the start of 2026, affecting OpenShift
curl -s "https://access.redhat.com/hydra/rest/securitydata/cve.json?severity=critical&after=2026-01-01&package=openshift&per_page=50" \
| jq -r '.[] | "\(.CVE) \(.public_date[:10]) — \(.bugzilla_description)"'
```

## Cross-reference with other skills

- **`update-advisor`** — Use this skill to validate any CVE IDs `update-advisor` cites in its risk report. Never repeat a CVE ID the agent hasn't checked against `/cve/<CVE-ID>.json`.
- **`product-lifecycle`** — When a CVE's `affected_release` lists a product, use `product-lifecycle` to confirm the product is still in a support phase that receives the advisory.

## Important

- **The `/cve/<CVE-ID>.json` endpoint is the source of truth for whether a CVE is recognized by Red Hat.** If it returns 404, do not assume the CVE applies to any Red Hat product — even if NVD or cve.org has an entry.
- **`package_state` and `affected_release` are mutually exclusive per product per CVE.** A product is in `package_state` when no fix has shipped (whatever the reason), and in `affected_release` once an advisory has shipped a fixed package.
- **`fix_state: "Will not fix"`, `"Out of support scope"`, and `"Affected"` are not all the same.** "Will not fix" is a deliberate decision; "Out of support scope" means the product version is past its support window; "Affected" means a fix is planned but not yet shipped.
- **Use `?per_page=` on search endpoints.** Default page size is small and the result set can be large; cap to what's needed.
- **`/cvrf/`, `/csaf/`, and direct advisory-detail endpoints are not available on this public API.** To get advisory contents, follow the public web URL at `https://access.redhat.com/errata/<RHSA-ID>` — but those pages are HTML, not JSON, and not appropriate to scrape from this skill. If full advisory contents are needed, surface the URL to the user.
- **Do not fabricate CVE IDs, RHSA IDs, or CVSS scores.** Only report values returned by these endpoints.
145 changes: 145 additions & 0 deletions support/redhat-support/references/security-data-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# Red Hat Security Data API Reference

## Endpoints

| Endpoint | Method | Purpose |
|---|---|---|
| `GET /hydra/rest/securitydata/cve/<CVE-ID>.json` | GET | Full detail for a single CVE |
| `GET /hydra/rest/securitydata/cve.json` | GET | Search/list CVEs with filters |

Base host: `https://access.redhat.com`

No authentication required.

## Search Filter Parameters (`/cve.json`)

| Parameter | Type | Description |
|---|---|---|
| `package` | string | Affects-package filter — substring match against `affected_packages` |
| `advisory` | string | Return CVEs included in the given advisory (e.g. `RHSA-2024:1614`) |
| `severity` | string | One of `low`, `moderate`, `important`, `critical` |
| `after` | date | ISO 8601 — only CVEs with `public_date` on/after |
| `before` | date | ISO 8601 — only CVEs with `public_date` on/before |
| `cwe` | string | CWE ID (e.g. `CWE-168`) |
| `bug` | string | Bugzilla ID |
| `per_page` | int | Page size (default is small; cap to what's actually needed) |
| `page` | int | 1-indexed page number |

Filters combine with AND. The endpoint returns a JSON array — empty `[]` when nothing matches.

## Single-CVE Detail Schema (`/cve/<CVE-ID>.json`)

| Field | Type | Description |
|---|---|---|
| `name` | string | CVE ID (echoes the path component) |
| `threat_severity` | string | `Critical` \| `Important` \| `Moderate` \| `Low` |
| `public_date` | string | ISO 8601 |
| `bugzilla` | object | `{ id, url, description }` |
| `cvss` | object | CVSS v2 (legacy; may be absent). When present: `{ cvss_base_score, cvss_scoring_vector, status }` |
| `cvss3` | object | CVSS v3. When present: `{ cvss3_base_score, cvss3_scoring_vector, status }` |

### `cvss3` sub-fields

| Field | Type | Description |
|---|---|---|
| `cvss3_base_score` | string | CVSS v3 base score as a decimal string (e.g. `"10.0"`) |
| `cvss3_scoring_vector` | string | CVSS v3 vector (e.g. `"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H"`) |
| `status` | string | `draft` \| `verified` |

| `cwe` | string | CWE ID, dash-prefixed |
| `details` | string[] | Multi-paragraph narrative description |
| `statement` | string | Red Hat's contextual statement (may be empty) |
| `acknowledgement` | string | Reporter credit |
| `mitigation` | object | `{ value, lang }` when present |
| `package_state` | object[] | Products with no released fix — see below |
| `affected_release` | object[] | Products where a fix has shipped — see below |
| `references` | string[] | External URLs (NVD, CVE.org, blog posts, KBs) |
| `upstream_fix` | string | Upstream version where the issue is fixed |

### `package_state[]` — pre-fix state

Per-product entries that describe how a CVE applies to a product **before** an advisory has shipped a fix.

| Field | Type | Description |
|---|---|---|
| `product_name` | string | Red Hat product name |
| `package_name` | string | Package within the product |
| `cpe` | string | CPE identifier |
| `fix_state` | string | See enumeration below |

`fix_state` values:

| Value | Meaning |
|---|---|
| `Affected` | Product is vulnerable; a fix is planned |
| `Not affected` | Product does not ship the vulnerable code path |
| `Will not fix` | Deliberate decision not to ship a fix (typically older releases) |
| `Out of support scope` | Product version is past its support window |
| `Under investigation` | Red Hat has not finished triage |
| `Fix deferred` | Acknowledged but de-prioritized |

### `affected_release[]` — post-fix state

Per-product entries for releases that **have** shipped a fix.

| Field | Type | Description |
|---|---|---|
| `product_name` | string | Red Hat product name |
| `release_date` | string | ISO 8601 advisory release date |
| `advisory` | string | RHSA / RHBA / RHEA ID (e.g. `RHSA-2024:1718`) |
| `cpe` | string | CPE identifier |
| `package` | string | Fixed package NVR (name-version-release) |

A product appears in **either** `package_state` or `affected_release` for a given CVE, not both.

The same `(product_name, advisory)` pair can appear multiple times in `affected_release` — typically once per architecture or sub-package. Use `unique_by(.advisory)` or `unique_by([.product_name, .advisory])` when listing or counting.

Product names also share base prefixes across support tiers. `"Red Hat Enterprise Linux 9"` (the base product), `"Red Hat Enterprise Linux 9.0 Extended Update Support"`, `"Red Hat Enterprise Linux 9.2 Extended Update Support"`, etc., are distinct entries. Use exact `==` match when targeting the base product only; use `startswith` only when the caller wants the whole family including EUS / AUS / E4S.

## Search List Schema (`/cve.json`)

Compact summary per CVE. Drill into `resource_url` for full data.

| Field | Type | Description |
|---|---|---|
| `CVE` | string | CVE ID |
| `severity` | string | Lowercase — `low` \| `moderate` \| `important` \| `critical` |
| `public_date` | string | ISO 8601 |
| `advisories` | string[] | All RHSAs that include this CVE (may be empty) |
| `bugzilla` | string | Bugzilla ID |
| `bugzilla_description` | string | Short summary |
| `CWE` | string | CWE ID |
| `cvss_score` | string\|null | CVSS v2 base score |
| `cvss_scoring_vector` | string\|null | CVSS v2 vector |
| `cvss3_score` | string\|null | CVSS v3 base score |
| `cvss3_scoring_vector` | string\|null | CVSS v3 vector |
| `affected_packages` | string[] | Fixed-package NVRs across all advisories |
| `package_state` | object[]\|null | Same shape as the single-detail endpoint when present |
| `resource_url` | string | Single-detail endpoint for this CVE |

Note: `severity` is lowercase in search results and capitalized in single-detail responses. The values are the same; the casing differs.

## What this API does **not** expose

These shapes are referenced elsewhere on access.redhat.com but are not available on this public endpoint:

| Wanted | Status | Workaround |
|---|---|---|
| Advisory (RHSA) body / errata text | Not on this API | Construct the public URL `https://access.redhat.com/errata/<RHSA-ID>` and surface it to the user — HTML, not JSON |
| CVRF / CSAF documents | Not on this API at the paths probed | None — surface the advisory URL |
| KB solutions (`/solutions/<id>`) | Authenticated, not part of the security data API | Out of scope for this skill |
| Bugzilla bug detail beyond the ID and summary | Separate Bugzilla API (`bugzilla.redhat.com`) | Outside the scope of this skill |

If a use case requires advisory contents, surface the public URL to the user rather than trying to fetch it via this API.

## Pagination and rate limits

- The endpoint does not return total counts in headers. To know if there are more results, request `per_page + 1` and check whether the extra entry came back.
- No documented public rate limit, but batch where possible — prefer one search call with `per_page=N` over `N` single-detail calls when only summary data is needed.

## Search Tips

1. **Validate first, then fetch.** A 404 from `/cve/<CVE-ID>.json` is the definitive "Red Hat does not track this CVE." Use it before doing any other work with a CVE ID.
2. **Use `?advisory=` to enumerate.** Given an RHSA, listing its CVEs via search is the fastest correlation.
3. **`?package=` is a substring match.** `openssh` matches both `openssh` and `openssh-clients`. Combine with `?severity=` and `?after=` to narrow.
4. **Search returns the lighter shape.** If you need `affected_release` or `package_state` detail, the `resource_url` on each search hit points to the single-detail endpoint.