Skip to content

generate-formula-api: attach vulnerabilities from advisory-database - #23341

Merged
andrew merged 3 commits into
Homebrew:mainfrom
andrew:vulns-api
Jul 31, 2026
Merged

generate-formula-api: attach vulnerabilities from advisory-database#23341
andrew merged 3 commits into
Homebrew:mainfrom
andrew:vulns-api

Conversation

@andrew

@andrew andrew commented Jul 28, 2026

Copy link
Copy Markdown
Member

Attaches a vulnerabilities field to each formula's public API JSON (_data/formula/<name>.json, api/formula/<name>.json) sourced from Homebrew/advisory-database rather than a live OSV.dev query per API build.

Vulns::AdvisoryDatabase is a CachedFeed reader for advisory-database's data/advisories.json (built nightly by rake advisories:concat, Homebrew/advisory-database#30). #status_for(name, pkg_version) evaluates every BREW-* record's ECOSYSTEM range against the given pkg_version via Vulnerability#range_status and returns:

{
  "open": [{"id": "BREW-...", "upstream": ["CVE-..."], "summary": "...", "severity": "high", "fix": null, "fixed_in": null}],
  "patched": [{"id": "BREW-...", "upstream": ["CVE-..."], "fix": "patch", "fixed_in": "6.0_29"}],
  "fixed_count": 3
}

open is records whose range still contains pkg_version; patched is records with ecosystem_specific.fix: "patch" (Homebrew ships a resolves-annotated patch) that pkg_version is past; fixed_count counts bump-fixed records that no longer apply. The key is absent for formulae with no records so consumers can distinguish "checked, clean" from "not covered".

generate-formula-api loads the feed once per build (24h cache TTL) and attaches the field per formula. A feed load failure opoos and the field is omitted so an advisory-database outage does not break the API build.

The internal API (FormulaStruct) and brew info are unchanged; those read from a fixed-field struct that does not carry this key yet and are a follow-up. formulae.brew.sh rendering is a separate PR to that repository.


  • Have you followed our Contributing guidelines?
  • Have you checked for other open Pull Requests for the same change?
  • Have you explained what your changes do? Performance claims (e.g. "this is faster") must include Hyperfine benchmarks.
  • Have you explained why you'd like these changes included, not just what they do?
  • For bug fixes, have you given step-by-step brew commands to reproduce the bug?
  • Have you written new tests (excluding integration tests)? Here's an example.
  • Have you successfully run brew lgtm (style, typechecking and tests) locally?

  • AI was used to generate or assist with generating this PR.

Claude Code assisted with implementation and tests; verified via brew lgtm and full brew style.


Vulns::AdvisoryDatabase reads Homebrew/advisory-database's published
data/advisories.json (built by that repository's rake advisories:concat)
via the same CachedFeed mechanism as Vulns::Repology, and evaluates each
BREW-* record's ECOSYSTEM range against a given pkg_version using
Vulnerability#range_status.

generate-formula-api loads it once per build and attaches
hash["vulnerabilities"] = {open:, patched:, fixed_count:} to each
formula's public API JSON (_data/formula/<name>.json and
api/formula/<name>.json). open is records whose range still contains
pkg_version; patched is records with ecosystem_specific.fix: patch that
pkg_version is past; fixed_count is bump-fixed records that no longer
apply. The key is absent for formulae with no records so consumers can
tell checked-and-clean from not-covered. A feed load failure is
opoo'd and the field is omitted so an advisory-database outage does not
break the API build.

The internal API (FormulaStruct) is unchanged; brew info reading the
field from there is a follow-up.
Copilot AI review requested due to automatic review settings July 28, 2026 16:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds vulnerability metadata from Homebrew/advisory-database to the public formula API JSON generated by brew generate-formula-api, avoiding per-build live OSV.dev queries.

Changes:

  • Introduces Homebrew::Vulns::AdvisoryDatabase as a cached feed reader for data/advisories.json.
  • Extends generate-formula-api to attach a per-formula vulnerabilities object (when available) and to gracefully omit it on feed load failure.
  • Adds unit tests for the new feed reader and updates the generate-formula-api command spec to cover the new behavior.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
Library/Homebrew/vulns/advisory_database.rb New cached feed reader + status_for API returning the public JSON shape.
Library/Homebrew/test/vulns/advisory_database_spec.rb New unit tests for feed validation, record wrapping, and status partitioning.
Library/Homebrew/dev-cmd/generate-formula-api.rb Loads advisory feed once per run and attaches vulnerabilities into public formula JSON.
Library/Homebrew/test/dev-cmd/generate-formula-api_spec.rb Updates command spec to cover presence/absence/omission-on-error of vulnerabilities.

馃挕 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Library/Homebrew/vulns/advisory_database.rb Outdated
Comment thread Library/Homebrew/test/vulns/advisory_database_spec.rb
Comment thread Library/Homebrew/vulns/advisory_database.rb
A record whose ECOSYSTEM range starts above pkg_version returns
state :not_applicable from range_status; that was falling through to
patched (if fix: patch) or fixed_count. Drop it instead so a version the
advisory never applied to is not counted either way. Also distinguish a
missing advisories key from a wrong-type value in the load error.
pull Bot pushed a commit to arc675/formulae.brew.sh that referenced this pull request Jul 29, 2026
Shows a Known vulnerabilities table when the formula's API JSON carries
vulnerabilities.open (populated by brew generate-formula-api from
Homebrew/advisory-database, Homebrew/brew#23341): each entry links its
first upstream id (or the BREW-* id when there is none) to
osv.dev/vulnerability/<id> with severity and truncated summary. When
vulnerabilities.patched is non-empty, lists the CVEs Homebrew ships a
resolves-annotated patch for. Nothing is rendered for formulae without
the field so "no records" is not misread as "no vulnerabilities".

@MikeMcQuaid MikeMcQuaid left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks!

@andrew
andrew enabled auto-merge July 31, 2026 08:07
@andrew
andrew added this pull request to the merge queue Jul 31, 2026
Merged via the queue into Homebrew:main with commit 55f2868 Jul 31, 2026
41 of 42 checks passed
@andrew
andrew deleted the vulns-api branch July 31, 2026 08:42
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.

3 participants