Skip to content

Combined doc update - PSMICRO-900 - binary expansion docs - #96

Open
dbaker-arch wants to merge 13 commits into
RedHatProductSecurity:mainfrom
dbaker-arch:dbaker-900
Open

Combined doc update - PSMICRO-900 - binary expansion docs#96
dbaker-arch wants to merge 13 commits into
RedHatProductSecurity:mainfrom
dbaker-arch:dbaker-900

Conversation

@dbaker-arch

Copy link
Copy Markdown

Combined docs update for binary expansion notes.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • Documentation
    • Updated CSAF/VEX guidance to reflect current advisory and VEX publication practices, scopes, profiles, product relationships, and package metadata.
    • Expanded RPM and repository metadata documentation, including package discovery and repository lookup guidance.
    • Clarified terminology and descriptions for CVE, CPE, PURL, product status, and modular RPMs.
    • Replaced outdated issue-tracker links with current Atlassian project references across the documentation.

Walkthrough

The documentation updates describe current CSAF/VEX publication practices, clarify RPM and repository guidance, expand product metadata definitions, and replace legacy SECDATA links with Red Hat Atlassian URLs.

Changes

Documentation guidance updates

Layer / File(s) Summary
CSAF and VEX model documentation
docs/csaf-vex.md
The guide now documents CSAF advisory and VEX files, profiles, publication scope, product identifiers, status fields, and binary and modular RPM expansion.
RPM and repository guidance
docs/scanning-vendors.md
The guide now distinguishes RPM types, explains SRPM queries and package discovery, and documents current repository metadata and lookup commands.
SECDATA feedback and project links
docs/csaf-vex.md, docs/purl.md, docs/sbom.md, docs/scanning-vendors.md, docs/vex-ga-details.md, docs/vex-ga.md
SECDATA references now use Red Hat Atlassian project links. The scanning guide also includes updated question and bug-report links.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies a combined documentation update focused on binary expansion notes, which is the main stated objective.
Description check ✅ Passed The description directly relates to the documentation changes and identifies the binary expansion focus.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🧹 Nitpick comments (1)
docs/csaf-vex.md (1)

43-43: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use descriptive link text.

Replace here with destination-specific text such as CSAF advisory directory, per-CVE VEX directory, and binary-RPM-aware VEX feed. This improves link discoverability and addresses the MD059 warnings.

Also applies to: 60-61

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/csaf-vex.md` at line 43, Update the links in docs/csaf-vex.md, including
the additional occurrences around lines 60–61, to replace generic “here” link
text with destination-specific labels such as “CSAF advisory directory,”
“per-CVE VEX directory,” and “binary-RPM-aware VEX feed,” while preserving the
existing URLs and surrounding content.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/csaf-vex.md`:
- Around line 204-206: Update the CPE definition in the documentation to
describe CPE as a structured naming scheme, not a centralized database; state
that the NVD hosts a dictionary of official CPE names, while preserving the
existing reference link.
- Around line 332-358: Update the RPM expansion documentation around “Binary RPM
Expansion” and “Modular RPM (rpmmod) Expansion” to define the consumer contract:
scanners must form product/component pairs, traverse module RPMs through
RPM-to-module and module-to-product relationships, and specify how to resolve
SRPM-level versus binary-RPM status mismatches so affectedness is neither
omitted nor misattributed. Align the wording with the relationship model
referenced in docs/scanning-vendors.md.
- Around line 5-9: Update the CSAF VEX coverage statement in the document
introduction to retain July 10, 2024 as the historical GA milestone while
qualifying the current effective scope and date, including the later all-CVE
rollout and subsequent removal of files based solely on public CVE data; link to
the Red Hat changelog for these changes if appropriate, and avoid implying that
an absent CVE indicates no association.
- Around line 132-133: Update the CSAF VEX field documentation to distinguish
document.tracking.id as the VEX document identifier and initial_release_date as
that document’s first publication date. Move CVE-specific metadata under
vulnerabilities[].cve, and document the Red Hat convention of using a CVE ID as
the document ID when applicable.

In `@docs/scanning-vendors.md`:
- Line 52: Update the RPM module statement in the documentation to say that RHEL
10 deprecates modularity and does not distribute modular RPM content, while
clarifying that module functionality is scheduled for removal in a future major
release. Avoid wording that implies rpmmod handling should be removed for all
RHEL releases.
- Around line 60-61: Update the documentation around RPM discovery to
distinguish regular packages from module streams and profiles: retain rpm -qa
for binary RPMs, document dnf module list --installed for RPM modules in
modularity-enabled content, and specify the fallback behavior when dnf is
unavailable.
- Around line 228-231: Align the rollout date in the legacy content manifest
section with the verified content-sets replacement date documented elsewhere,
replacing the conflicting July 2025 date while preserving the deprecation
guidance.
- Around line 328-334: Update the vendor-scanning documentation and
implementation described around the binary RPM repository lookup to use an
installed-package/transaction-scoped query, such as DNF5’s --installed query
with %{from_repo}, instead of unscoped dnf repoquery metadata. Ensure the
scanner emits only the repository recorded at installation time, preventing
currently available but uninvolved repositories from reaching the CPE-mapping
step.

---

Nitpick comments:
In `@docs/csaf-vex.md`:
- Line 43: Update the links in docs/csaf-vex.md, including the additional
occurrences around lines 60–61, to replace generic “here” link text with
destination-specific labels such as “CSAF advisory directory,” “per-CVE VEX
directory,” and “binary-RPM-aware VEX feed,” while preserving the existing URLs
and surrounding content.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6079703c-33d2-4766-a0aa-15f476c58ae1

📥 Commits

Reviewing files that changed from the base of the PR and between b1abb59 and f621f10.

📒 Files selected for processing (6)
  • docs/csaf-vex.md
  • docs/purl.md
  • docs/sbom.md
  • docs/scanning-vendors.md
  • docs/vex-ga-details.md
  • docs/vex-ga.md

Comment thread docs/csaf-vex.md
Comment on lines +5 to +9
Starting July 10th, 2024, Red Hat Product Security publishes CSAF advisory files for
every Red Hat Security Advisory
([RHSA](https://access.redhat.com/articles/explaining_redhat_errata)) published, as well
as CSAF VEX files for every CVE record that is associated with the Red Hat portfolio
in any way.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Date and qualify the VEX coverage statement.

This text reads as the current publication scope. Red Hat’s changelog records a broader all-CVE rollout on February 3, 2025, followed by a June 12, 2026 decision to remove VEX files generated solely from public CVE data. Keep July 10, 2024 as the historical GA milestone, but state the effective scope and date or link readers to the changelog. Otherwise, consumers can make incorrect assumptions about what an absent CVE means. (access.redhat.com)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/csaf-vex.md` around lines 5 - 9, Update the CSAF VEX coverage statement
in the document introduction to retain July 10, 2024 as the historical GA
milestone while qualifying the current effective scope and date, including the
later all-CVE rollout and subsequent removal of files based solely on public CVE
data; link to the Red Hat changelog for these changes if appropriate, and avoid
implying that an absent CVE indicates no association.

Comment thread docs/csaf-vex.md
Comment on lines +132 to +133
* `id`: Provides the official CVE ID, as published by [NVD](https://nvd.nist.gov).
* `initial_release_date`: Represents the date that Red Hat first published information on the CVE.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

curl -fsSL 'https://docs.oasis-open.org/csaf/csaf/v2.0/os/csaf-v2.0-os.html' |
  rg -n -A8 -B3 \
    'Unique identifier for the document|Initial release date .* document was first published'

Repository: RedHatProductSecurity/security-data-guidelines

Length of output: 2152


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the relevant CSAF/VEX documentation context and nearby examples.
printf 'Relevant docs/csaf-vex.md lines:\n'
sed -n '100,155p' docs/csaf-vex.md | cat -n

printf '\nSearch for id/cve/document.tracking in docs/csaf-vex.md:\n'
rg -n 'tracking|vulnerabilities|cve|id|initial_release_date' docs/csaf-vex.md || true

Repository: RedHatProductSecurity/security-data-guidelines

Length of output: 7694


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
p = Path("docs/csaf-vex.md")
s = p.read_text()
lines = s.splitlines()
block_start = next(i for i, line in enumerate(lines) if line.startswith('```json') and i > 0 and 'tracking' in '\n'.join(lines[max(0,i-30):i]))
block_end = next(i for i, line in enumerate(lines[block_start:], block_start) if line.startswith('```')) + block_start
schema = '\n'.join(lines[block_start:block_end])
print("Contains document.tracking id:", "document.tracking.id" in schema or '"id"' in schema)
print("Contains vulnerability cve examples:", "cve" in schema)
for i, line in enumerate(lines[block_start:block_end], block_start):
    if "id" in line or "initial_release_date" in line:
        print(f"{i}: {line}")
PY

printf '\nJSON example from docs/csaf-vex.md around CVE and vulnerabilities:\n'
sed -n '280,400p' docs/csaf-vex.md | cat -n

Repository: RedHatProductSecurity/security-data-guidelines

Length of output: 271


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'Context around CVE metadata in docs/csaf-vex.md:\n'
sed -n '335,385p' docs/csaf-vex.md | cat -n

printf '\nExact docs/csaf-vex.md line 132-133:\n'
sed -n '132,133p' docs/csaf-vex.md

printf '\nAll occurrences of document.tracking and CSAF/CSAF-like examples:\n'
rg -n 'document\.tracking|document tracking|tracking\.' docs/csaf-vex.md csaf-vex || true

Repository: RedHatProductSecurity/security-data-guidelines

Length of output: 3069


Use CSAF tracking semantics for VEX document fields.

document.tracking.id identifies the CSAF VEX document. initial_release_date is the first publication date for that CSAF document. Document CVE metadata under vulnerabilities[].cve, and describe the Red Hat convention if VEX documents use CVE IDs as the document ID.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/csaf-vex.md` around lines 132 - 133, Update the CSAF VEX field
documentation to distinguish document.tracking.id as the VEX document identifier
and initial_release_date as that document’s first publication date. Move
CVE-specific metadata under vulnerabilities[].cve, and document the Red Hat
convention of using a CVE ID as the document ID when applicable.

Comment thread docs/csaf-vex.md
Comment on lines +204 to +206
CPE stands for Common Platform Enumeration, and refers to a centralised database (https://nvd.nist.gov/products/cpe) that
stores unique identifiers that allow you to refer to specific versions of released products or components.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Use the standard CPE definition.

CPE is a structured naming scheme. The NVD hosts a dictionary of official CPE names. CPE itself is not the database. Red Hat also notes that some Red Hat CPE names can be temporary and absent from the official dictionary. (nvd.nist.gov)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/csaf-vex.md` around lines 204 - 206, Update the CPE definition in the
documentation to describe CPE as a structured naming scheme, not a centralized
database; state that the NVD hosts a dictionary of official CPE names, while
preserving the existing reference link.

Comment thread docs/csaf-vex.md
Comment on lines +332 to +358
#### Binary RPM Expansion

RPMs can have either a one-to-one or one-to-many mapping between the Source RPM and Binary RPM(s).
Binary expansion allows the VEX data to offer a more fine-grained level of detail to describe
where vulnerabilities are present, and where they are fixed,

Expanding single SRPMs to multiple binary RPMs comes with a potential issue when data in different places
refers to different levels. As binary expansion is rolled out, there may be a case where a CSAF Advisory
mentions a fix being made to a Source RPM, but a corresponding VEX File for the CVE listing it as being
fixed in the individual Binary RPMs.

At the present time, End of Life (EOL) products have limited binary expansion available due to them
pre-dating the current system and missing the level of data needed to perform the mapping.

#### Modular RPM (rpmmod) Expansion

Similar to Binary RPM Expansion, a similiar concept applies to `rpmmod` content. In the event
that a vulnerability affects the module (the rpmmod entity) it is unlikely to affect every RPM
that the module consists of.

Expanding rpmmod level information to rpm level allows for fine-grained detail to capture
the affectedness of the specific packages.

As with the above, there is the need to map `rpmmod` entities to their constituent parts, and to
map in the inverse to identify what rpmmod a given part may belong to.


Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Define the RPM expansion contract for consumers.

This section names source-to-binary and module-to-RPM mappings, but it does not define the relationship traversal or status rule that scanners must use. In docs/scanning-vendors.md, vendors must form product/component pairs. Document that module RPMs are mapped through the RPM-to-module and module-to-product relationships, and explain how consumers handle the stated SRPM-versus-binary status mismatch. Without this rule, scanners can omit or misattribute affectedness. Red Hat’s changelog documents this indirect module relationship model. (access.redhat.com)

🧰 Tools
🪛 LanguageTool

[style] ~342-~342: ‘At the present time’ might be wordy. Consider a shorter alternative.
Context: ...g fixed in the individual Binary RPMs. At the present time, End of Life (EOL) products have limite...

(EN_WORDINESS_PREMIUM_AT_THE_PRESENT_TIME)


[style] ~348-~348: ‘In the event that’ might be wordy. Consider a shorter alternative.
Context: ...r concept applies to rpmmod content. In the event that a vulnerability affects the module (the...

(EN_WORDINESS_PREMIUM_IN_THE_EVENT_THAT)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/csaf-vex.md` around lines 332 - 358, Update the RPM expansion
documentation around “Binary RPM Expansion” and “Modular RPM (rpmmod) Expansion”
to define the consumer contract: scanners must form product/component pairs,
traverse module RPMs through RPM-to-module and module-to-product relationships,
and specify how to resolve SRPM-level versus binary-RPM status mismatches so
affectedness is neither omitted nor misattributed. Align the wording with the
relationship model referenced in docs/scanning-vendors.md.

Comment thread docs/scanning-vendors.md
exclude non-affected binary packages from vulnerabilities that are present in
the shared source.

Additionally, an RPM module is a set of RPM packages that represent a higher level software component that is installed together. AppStreams are a common example of RPM modules. Note that RPM module support was removed in RHEL 10.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file excerpt =="
sed -n '45,58p' docs/scanning-vendors.md || true

echo
echo "== nearby rpmmod/usages =="
rg -n "RPM module|module support|removed in RHEL|RHEL 10|rpmmod|deprecat|modularity" docs/scanning-vendors.md docs -S || true

Repository: RedHatProductSecurity/security-data-guidelines

Length of output: 7546


🌐 Web query:

Red Hat RHEL 10 modularity no modular content distributed deprecated removal future major release documentation

💡 Result:

In Red Hat Enterprise Linux (RHEL) 10, modularity functionality is deprecated and is scheduled to be removed in a future major release [1][2]. Key points regarding the status of modularity in RHEL 10 include: - No Modular Content: Red Hat does not intend to provide any Application Streams that use modularity as a packaging technology in RHEL 10 [1][3][4]. Consequently, no modular content is being distributed with RHEL 10 [2][5]. - Deprecation Warnings: Because modularity is deprecated, the DNF module command in RHEL 10 displays a deprecation warning [1][2]. - Kickstart Changes: Support for DNF modularity in the Anaconda installer has been deprecated, and the module Kickstart command is also deprecated [1][6]. Users utilizing modules in the %packages section of Kickstart files or the module Kickstart command will be impacted [1][7]. - Shift in Application Streams: While RHEL 10 continues to offer Application Streams for user-space components, these are provided as standard RPM packages that can be installed using the dnf install command, rather than through the modularity extension format used in previous RHEL major versions [5][4]. This transition is part of an effort to simplify the installation process and ensure a more consistent experience [1][7]. While deprecated features in RHEL 10 remain fully supported for the duration of the current release, they are not recommended for new deployments due to their planned removal in future major versions [6].

Citations:


Correct the RHEL 10 module statement.

RHEL 10 treats modularity as deprecated and does not distribute modular RPM content, but the functionality is scheduled for removal in a future major release. Rewrite this sentence to avoid telling scanners to drop rpmmod handling for all RHEL releases.

🧰 Tools
🪛 LanguageTool

[grammar] ~52-~52: Use a hyphen to join words.
Context: ... of RPM packages that represent a higher level software component that is install...

(QB_NEW_EN_HYPHEN)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/scanning-vendors.md` at line 52, Update the RPM module statement in the
documentation to say that RHEL 10 deprecates modularity and does not distribute
modular RPM content, while clarifying that module functionality is scheduled for
removal in a future major release. Avoid wording that implies rpmmod handling
should be removed for all RHEL releases.

Sources: Path instructions, MCP tools

Comment thread docs/scanning-vendors.md
Comment on lines +60 to +61
Both binary RPMs and RPM modules installed on a host (or in a container image) can be discovered using the `rpm -qa` command from within the system. In this case the `-qa` refers to `q` (query) and `a` (all installed packages), and the `--qf` specifies
the format to use for each installed package.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

rpm -qa | head
if command -v dnf >/dev/null 2>&1; then
  dnf module list --installed
fi

Repository: RedHatProductSecurity/security-data-guidelines

Length of output: 225


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "== locate file =="
git ls-files | grep -F 'docs/scanning-vendors.md' || true

echo "== section around lines 50-90 =="
sed -n '50,90p' docs/scanning-vendors.md

echo "== rpmmod/rpm -qa/dnf module occurrences =="
rg -n "rpm -qa|rpmmod|rpm_module|module list|--installed|Module|module" docs/scanning-vendors.md

Repository: RedHatProductSecurity/security-data-guidelines

Length of output: 3611


🌐 Web query:

Red Hat Enterprise Linux dnf module list --installed module streams rpmmod identifiers

💡 Result:

In Red Hat Enterprise Linux, the command dnf module list --installed is used to list module streams that have profiles currently installed on your system [1][2]. Key concepts related to your query: Module Streams A module stream is a collection of RPM packages that acts as a virtual repository [3][4]. It represents a specific version of a component (e.g., nodejs:18, postgresql:15) [5][3]. Streams allow you to install specific versions of software independently of the core operating system's lifecycle [6][7]. Only one stream of a particular module can be active at any given time [3][4]. RPM Modularity Identifiers Modular packages are packages that belong to a specific module [3][4]. They are identified by having a %{modularitylabel} RPM header set, which links the package to its specific module stream [3][4]. This label is used by DNF to ensure that package dependencies are resolved correctly within the context of the active module stream, preventing conflicts between different versions of the same software [3][4]. Command Output When you run dnf module list --installed, the output displays the status of modules on your system [5][8]. The output typically includes columns for the module Name, the active/available Stream, the installed Profiles, and a summary [5][8]. DNF uses indicators to denote the state of these streams and profiles [5][8]: [d]: Default stream or profile. [e]: Enabled stream. [x]: Disabled stream. [i]: Installed profile. By using the --installed flag, you filter the list to show only those modules where at least one profile is currently installed [5][1].

Citations:


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "== RPM modules section =="
sed -n '95,115p' docs/scanning-vendors.md

echo "== broader RPM modularity label references =="
rg -n "rpmmod|rpmmodifiers|modularitylabel|modularity|module list|--installed|Binary RPMs|RPM modules" docs/scanning-vendors.md

Repository: RedHatProductSecurity/security-data-guidelines

Length of output: 2905


Use a module-aware command for RPM module discovery.

rpm -qa lists installed RPM packages and does not report installed module streams or profiles needed for rpmmod purl qualifiers. Use rpm -qa for RPM packages and dnf module list --installed for RPM modules in RHEL/modularity-eligible content. Document the fallback when dnf is unavailable.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/scanning-vendors.md` around lines 60 - 61, Update the documentation
around RPM discovery to distinguish regular packages from module streams and
profiles: retain rpm -qa for binary RPMs, document dnf module list --installed
for RPM modules in modularity-enabled content, and specify the fallback behavior
when dnf is unavailable.

Sources: Path instructions, MCP tools

Comment thread docs/scanning-vendors.md
Comment on lines +228 to +231
Starting in June 2020, Content manifest JSON files were included for each layer
in the container image in the `root/buildinfo/` directory. In July 2025 this
system was replaced (see below) with content-sets, and will be deprecated at
some point in the future.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Locate file =="
git ls-files | rg '(^|/)docs/scanning-vendors\.md$' || true

echo "== Relevant sections =="
if [ -f docs/scanning-vendors.md ]; then
  wc -l docs/scanning-vendors.md
  sed -n '210,305p' docs/scanning-vendors.md | nl -ba -v210
fi

echo "== Date occurrences in file =="
rg -n 'January 2025|July 2025|June 2020|content-sets|Content Sets|Content manifest|legacy|deprecated|deprecat' docs/scanning-vendors.md || true

Repository: RedHatProductSecurity/security-data-guidelines

Length of output: 321


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Relevant sections =="
sed -n '210,305p' docs/scanning-vendors.md

echo
echo "== Date occurrences in file =="
rg -n 'January 2025|July 2025|June 2020|content-sets|Content Sets|Content manifest|legacy|deprecated|deprecat' docs/scanning-vendors.md || true

Repository: RedHatProductSecurity/security-data-guidelines

Length of output: 5343


🌐 Web query:

Red Hat content-manifest replacement content-sets January 2025 July 2025

💡 Result:

There is no official replacement of the Red Hat Satellite "content-manifest" with "content-sets" scheduled for January or July 2025. Red Hat Satellite continues to use subscription manifests as the primary method for importing subscription allocations and enabling access to Red Hat Content Delivery Network (CDN) repositories [1][2][3]. The concepts of "manifests" and "content sets" serve different functions within the Red Hat ecosystem: 1. Subscription Manifests: These are encrypted files exported from the Red Hat Hybrid Cloud Console and imported into Satellite. They contain your organization's subscription entitlements, which authorize the Satellite server to access and synchronize content from the Red Hat CDN [3][4]. This process remains the standard procedure in current versions of Satellite (e.g., 6.19) [2][3]. 2. Content Sets: This term generally refers to the specific collection of repositories (e.g., RHEL 8 baseos, appstream) defined within the manifest or mapped to systems [5]. It is not a replacement for the manifest itself; rather, the manifest acts as the container that makes these content sets accessible to your Satellite organization [3][4]. Red Hat has been transitioning away from legacy "entitlement-based" subscription models in favor of "Simple Content Access" (SCA), which simplifies how entitlements are consumed [4][6]. While SCA changes how subscriptions are enforced, it does not remove the need for a subscription manifest to authenticate and provide access to the content [3][4]. If you have encountered information regarding a change or "replacement," it likely refers to the ongoing migration toward SCA, which is the recommended best practice for modern Satellite deployments [6][7].

Citations:


🌐 Web query:

red-hat-policies container manifest json content-sets January 2025 July 2025 buildinfo

💡 Result:

Red Hat container images typically include build information within the /root/buildinfo directory, which is used to store metadata about the image's origin and construction [1][2]. Content-sets and manifest JSON files: The /root/buildinfo/content_manifests/ directory contains JSON files (such as content-sets.json) that document the Yum repositories (content sets) from which the image's RPM content was sourced [3][4]. These files generally follow a schema defined by the Red Hat container build system (Atomic Reactor) [3]. In recent images, these JSON files may include an image_contents array and a content_sets list [3]. Some historical or specific builds have exhibited malformed content set names with trailing numeric suffixes (e.g., 8), which necessitated updates in security scanning tools like Trivy to correctly parse the manifests [5][3]. Security tools rely on these manifest files to map image contents to Common Platform Enumeration (CPE) indices for vulnerability scanning [5]. Build Info Context: The /root/buildinfo directory also typically contains the Dockerfile(s) used to build the image [1][2]. This allows users to inspect the build process, including the base image used, installed packages, and other configuration layers [1][6]. Distinction from policy.json: It is important to distinguish this metadata from containers-policy.json, which is a system-wide configuration file used for container image signature verification and trust policies [7][8][9]. Similarly, ImageContentPolicy is an OpenShift-specific API resource used to manage registry mirror configurations for images, rather than metadata about an individual image's build contents [10]. For official Red Hat images, this metadata is generated during the build process and is consistent with the information managed in Red Hat's Pyxis container catalog [11]. If a container image lacks these specific files, it may be due to it being a non-Red Hat image or a specialized image type (e.g., minimal images) where standard manifest contents might differ [4].

Citations:


🌐 Web query:

Red Hat security-data-guidelines docs/scanning-vendors.md January 2025 July 2025 content-sets

💡 Result:

The Red Hat security-data-guidelines documentation, specifically the scanning-vendors.md file (found in the RedHatProductSecurity/security-data-guidelines repository), provides technical guidance for vulnerability scanning vendors on how to accurately report on Red Hat container images [1][2]. Regarding the transition involving content-sets.json: Starting from January 2025, Red Hat replaced the legacy content manifest JSON files (previously located in /root/buildinfo/) with a single content-sets.json file [2]. This file is located in /usr/share/buildinfo/content-sets.json, though for compatibility, the same content is also copied to the legacy location /root/buildinfo/content_manifests/ [2]. Scanning vendors are advised that because access to the root directory may be locked in some container images, the /root/buildinfo/ location will eventually be deprecated, making /usr/share/buildinfo/ the primary location for this metadata [2]. The content-sets.json file contains a content_sets object that lists the repository names providing the packages found in the container image, which is essential for accurate product and vulnerability correlation [2]. As of July 2024, Red Hat shifted its security advisory publishing to exclusively use the Common Security Advisory Framework (CSAF) and the Vulnerability Exploitability eXchange (VEX) profile for all security advisories and CVE-associated vulnerability data [3][4]. Certified vulnerability scanning vendors are required to use this CSAF-VEX data as the standard source for identifying and reporting Red Hat CVEs to ensure accuracy and consistency [5][6].

Citations:


Use a single rollout date for content-set metadata.

Content Sets JSON files states the replacement starts January 2025, but the legacy section says July 2025. Use one verified date here so users do not choose the wrong metadata path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/scanning-vendors.md` around lines 228 - 231, Align the rollout date in
the legacy content manifest section with the verified content-sets replacement
date documented elsewhere, replacing the conflicting July 2025 date while
preserving the deprecation guidance.

Source: Path instructions

Comment thread docs/scanning-vendors.md
Comment on lines +328 to +334
Although container images provide a list of repositories from which the
packages in the image are sourced, vendors may also be interested in
determining the repository that provided a specific binary RPM. It is possible
for multiple repositories to contain the same binary RPMs - this command lets
you query the system to determine which repository was used at install time.
Note that `dnf` is not always shipped with container images.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

pkg="${1:-libgcc-11.3.1-4.3.el9.x86_64}"
dnf repoquery --qf '%{repoid}' "$pkg"
dnf list installed "$pkg"

Repository: RedHatProductSecurity/security-data-guidelines

Length of output: 225


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

# Inspect the referenced documentation section and nearby context.
if [ -f docs/scanning-vendors.md ]; then
  echo "== docs/scanning-vendor.md lines 300-350 =="
  sed -n '300,350p' docs/scanning-vendors.md | nl -ba -v300
else
  echo "docs/scanning-vendors.md not found"
fi

echo
echo "== occurrences of repoquery within docs/scanning-vendors.md =="
rg -n "repoquery|repoid|installed|history" docs/scanning-vendors.md || true

Repository: RedHatProductSecurity/security-data-guidelines

Length of output: 268


🌐 Web query:

DNF command reference repoquery --qf %{repoid} installed package repository install location

💡 Result:

To display the repository a package was installed from using the DNF repoquery command, you should use the from_repo tag instead of repoid [1][2]. The repoid tag typically displays the repository ID currently associated with an available package, whereas from_repo specifically identifies the repository from which an installed package originated [1][2]. To output the repository of an installed package, use the following command: dnf repoquery --installed --qf "%{name} %{from_repo}" If you are using dnf5, this command remains the standard way to retrieve that information [1][3]. The %{from_repo} tag is specifically designed to return the ID of the repository the package was installed from; this field will be empty if the package was not installed from a repository (e.g., installed manually via rpm) [1][2]. For a more comprehensive view, you can also use: dnf repoquery --installed --qf "%{name}: %{from_repo}" If you only need to list installed packages from a specific repository, you can filter using the --installed-from-repo option in dnf5 [2][4]: dnf repoquery --installed --installed-from-repo=<repo_id> Alternatively, the dnf repository-packages command provides a built-in way to list packages installed from a specific repository without needing custom format strings [5][6]: dnf repository-packages <repo_id> list --installed

Citations:


🌐 Web query:

DNF command reference installed repository packages from_repo --installed-from-repo

💡 Result:

The --installed-from-repo option is a feature introduced in DNF5 to filter packages based on the repository from which they were originally installed [1][2][3]. It replaces functionality previously provided by the repository-packages command in DNF4 [1][3]. Usage and Functionality The --installed-from-repo=REPO_ID option filters operations (such as list, info, remove, reinstall, upgrade, etc.) to target only packages installed from a specific repository [1][2]. For example, to list all packages installed from a specific repository, you can use: dnf5 list --installed --installed-from-repo=REPO_ID [3] This option is applicable to various DNF5 commands, including [1][2]: - list: To display packages [1][3] - info: To show detailed package information [1][2] - repoquery: To query package metadata [1][2] - remove, reinstall, upgrade, downgrade, distro-sync, and swap: To perform maintenance on packages originating from a specific source [1][2] Comparison with DNF4 In DNF4, the command dnf repository-packages list --installed was commonly used to achieve this [4][5][6]. In DNF5, the repository-packages command has been dropped, and its functionality is now covered by combining existing commands with options like --installed-from-repo [1][3]. Note: If you are using DNF5, verify your specific version's command availability, as this option was added to provide a direct, more efficient way to filter packages by their source repository [2][3].

Citations:


🌐 Web query:

DNF4 repoquery installed repository origin how to determine installed package repository dnf

💡 Result:

To determine the repository from which an installed package originated using DNF, you can use several methods depending on whether you are querying a specific package or listing packages by repository. For DNF5 (the modern version of DNF), you can use the built-in query format feature with dnf5 repoquery [1][2]: dnf5 repoquery --installed --queryformat "%{name} %{from_repo}" <package_name> For both DNF4 and DNF5, you can use the dnf info command to see the repository origin for a specific package [3]: dnf info <package_name> Look for the "From repo" line in the output [4][3]. To list all installed packages from a specific repository (REPONAME), you can use: dnf repository-packages list installed [5] Alternatively, a common approach for DNF4 is to use the list command combined with grep [6][5]: dnf list installed | grep @ Note that in the output of many DNF commands, a repository name preceded by an "@" symbol (e.g., @updates) indicates the repository from which that package was installed [4][3][6]. If the output shows @System, it often means the package was installed from a local source, manually, or its original repository metadata is no longer tracked or available [4][3].

Citations:


🌐 Web query:

DNF repoquery repo query install repo name from repo installed package DNF4 DNF5

💡 Result:

To determine which repository an installed package originated from using DNF, you can use the repoquery command. While DNF4 and DNF5 have some syntax differences, both provide tools to inspect this metadata [1][2]. DNF5 (The modern implementation) In DNF5, you can use query tags to explicitly display the repository information for installed packages [3][4]. Use the following command format: dnf5 repoquery --installed --queryformat "%{name}: %{from_repo}" <package_name> [4] The from_repo tag displays the ID of the repository from which the package was installed [3][5]. You can also filter packages based on their origin repository using the --installed-from-repo=<repo_id> option [5][6]. DNF4 (The legacy implementation) In DNF4, the repoquery command is typically used with the --info flag, which provides detailed package information including the "From repo" field [7]. dnf repoquery --info --installed <package_name> [7] Additionally, for both versions, you can use the standard dnf info command: dnf info <package_name> [8] Look for the "From repo" field in the output. Note that if this field is missing or says "installed," it may indicate the package was installed manually (e.g., via rpm -i) or the metadata is no longer available in the current repository cache [9][8]. Summary of Differences * Querying: DNF5 has streamlined the repoquery command, dropping several legacy aliases (like repoquery-n, repoquery-na) and changing how certain flags like --resolve (now replaced by --providers-of=) work [1][2][10]. * Formatting: DNF5's --queryformat option is more aligned with rpm --query behavior and no longer adds automatic newlines, requiring explicit \n if needed [1][2]. * Consistency: Both versions remain the authoritative way to query this metadata, but always check your specific version's man page (man dnf5-repoquery or man dnf-repoquery) for nuances in your distribution [5][11][4].

Citations:


🌐 Web query:

Red Hat DNF commands determine installed package repository from repo repoquery DNF4

💡 Result:

To determine the repository from which an installed package originated using DNF4, you can use the dnf repoquery command with a custom query format. The most effective way to display the source repository of an installed package is to use the --queryformat option to output the repository name tag (reponame) [1]: dnf repoquery --installed --queryformat '%{name}: %{reponame}' <package_name> In this command: - --installed limits the query to packages currently installed on your system [2]. - --queryformat '%{name}: %{reponame}' instructs DNF to print the package name followed by the ID of the repository it was installed from [1]. Note that for packages that were not installed from a configured repository (or if the repository metadata is no longer available), this field may appear empty or show @System (which indicates the package is managed by the local RPM database rather than a specific remote repository) [3][4]. While standard commands like dnf info <package_name> show package details, they do not always explicitly list the "From repo" field for already installed packages on all DNF4 versions, making the repoquery method more reliable for this specific task [4][2].

Citations:


🌐 Web query:

site:man7.org Linux dnf repoquery man "%{reponame}" "%{from_repo}" repoquery --installed

💡 Result:

The command structure you referenced is not a standard DNF command syntax. The DNF repoquery command is used to query metadata from repositories, and when combined with the --installed flag, it queries the local RPM database instead of remote repositories [1][2][3]. The placeholders %{reponame} and %{from_repo} are not CLI arguments for the dnf or repoquery command; they are query tags used with the --queryformat option to display specific metadata [2][4]. To display the repository a package was originally installed from, you can use the --queryformat option to extract that information from the local database [4]. Example usage: To list all installed packages along with the name of the repository they were installed from, use: dnf repoquery --installed --queryformat "%{name}: %{from_repo}" Explanation of components: --installed: Restricts the query to packages currently installed on the system (querying the local RPM database) [1][3]. --queryformat: Specifies a custom output format [2]. %{name}: A tag that prints the package name [4]. %{from_repo}: A tag that prints the repository ID from which the package was originally installed (this information is stored in the local yum/dnf database) [5][4]. Note: The information for %{from_repo} is tracked by the local package manager database (often accessed via yumdb or dnf internal records) [5]. If a package was installed manually (e.g., via rpm -i or from a local file), this field may be empty or indicate it was not installed from a configured repository [5].

Citations:


Do not derive install-time provenance from an unscoped dnf repoquery.

dnf repoquery --qf '%{repoid}' searches available repository metadata. Use an installed-package/transaction query, such as dnf repoquery --installed --queryformat '%{name}: %{from_repo}' <package> on DNF5, and update the scanner to avoid emitting repositories that only currently contain the package. The following CPE-mapping step can otherwise write wrong product-identification data.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/scanning-vendors.md` around lines 328 - 334, Update the vendor-scanning
documentation and implementation described around the binary RPM repository
lookup to use an installed-package/transaction-scoped query, such as DNF5’s
--installed query with %{from_repo}, instead of unscoped dnf repoquery metadata.
Ensure the scanner emits only the repository recorded at installation time,
preventing currently available but uninvolved repositories from reaching the
CPE-mapping step.

Sources: Path instructions, MCP tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant