Files
git.stella-ops.org/src/StellaOps.Concelier.Connector.Vndr.Apple

Apple Security Updates Connector

Feed contract

The Apple Software Lookup Service (https://gdmf.apple.com/v2/pmv) publishes JSON payloads describing every public software release Apple has shipped. Each AssetSet entry exposes:

  • ProductBuildVersion, ProductVersion, and channel flags (e.g., RapidSecurityResponse)
  • Timestamps for PostingDate, ExpirationDate, and PreInstallDeadline
  • Associated product families/devices (Mac, iPhone, iPad, Apple TV, Apple Watch, VisionOS)
  • Metadata for download packages, release notes, and signing assets

The service supports delta polling by filtering on PostingDate and ReleaseType; responses are gzip-compressed and require a standard HTTPS client.citeturn3search8

Apples new security updates landing hub (https://support.apple.com/100100) consolidates bulletin detail pages (HT articles). Each update is linked via an HT identifier such as HT214108 and lists:

  • CVE identifiers with Apples internal tracking IDs
  • Product version/build applicability tables
  • Mitigation guidance, acknowledgements, and update packaging notesciteturn1search6

Historical advisories redirect to per-platform pages (e.g., macOS, iOS, visionOS). The HTML structure uses <section data-component="security-update"> blocks with nested tables for affected products. CVE rows include disclosure dates and impact text that we can normalise into canonical AffectedPackage entries.

Change detection strategy

  1. Poll the Software Lookup Service for updates where PostingDate is within the sliding window (lastModified - tolerance). Cache ProductID + PostingDate to avoid duplicate fetches.
  2. For each candidate, derive the HT article URL from DocumentationURL or by combining the HT identifier with the base path (https://support.apple.com/{locale}/). Fetch with conditional headers (If-None-Match, If-Modified-Since).
  3. On HTTP 200, store the raw HTML + metadata (HT id, posting date, product identifiers). On 304, re-queue existing documents for mapping only.

Unofficial Apple documentation warns that the Software Lookup Service rate-limits clients after repeated unauthenticated bursts; respect 5 requests/second and honour Retry-After headers on 403/429 responses.citeturn3search3

Parsing & mapping notes

  • CVE lists live inside <ul data-testid="cve-list"> items; each <li> contains CVE, impact, and credit text. Parse these into canonical Alias + AffectedPackage records, using Apples component name as the package name and the OS build as the range primitive seed.
  • Product/version tables have headers for platform (Platform, Version, Build). Map the OS name into our vendor range primitive namespace (apple.platform, apple.build).
  • Rapid Security Response advisories include an Rapid Security Responses badge; emit psirt_flags with apple.rapid_security_response = true.

Outstanding questions

  • Some HT pages embed downloadable PDFs for supplemental mitigations. Confirm whether to persist PDF text via the shared PdfTextExtractor.
  • Vision Pro updates include deviceFamily identifiers not yet mapped in RangePrimitives. Extend the model with apple.deviceFamily once sample fixtures are captured.

Fixture maintenance

Deterministic regression coverage lives in src/StellaOps.Concelier.Connector.Vndr.Apple.Tests/Apple/Fixtures. When Apple publishes new advisories the fixtures must be refreshed using the provided helper scripts:

  • Bash: ./scripts/update-apple-fixtures.sh
  • PowerShell: ./scripts/update-apple-fixtures.ps1

Both scripts set UPDATE_APPLE_FIXTURES=1, touch a .update-apple-fixtures sentinel so test runs inside WSL propagate the flag, fetch the live HT articles referenced in AppleFixtureManager, sanitise the HTML, and rewrite the paired .expected.json DTO snapshots. Always inspect the resulting diff and re-run dotnet test src/StellaOps.Concelier.Connector.Vndr.Apple.Tests/StellaOps.Concelier.Connector.Vndr.Apple.Tests.csproj without the environment variable to ensure deterministic output before committing.