◐partialThe exact component-and-version inventory the boundary's repositories build from — every package the dependency graph resolved, carrying the version string that is the only thing SA-22's question can be asked about — together with whether that graph is switched on across the boundary at all, and then the open advisories for which the ecosystem offers no patched version, which is the closest thing a pipeline emits to a component nobody maintains any more. The inventory is the load-bearing half and it is why this recipe exists separately from the vulnerability one: "is this component past end of support" is a question about a name and a version, and a check that cannot produce the version has not asked it.monthlyapi
unsupported-component-inventory-and-lifecycle-reviewGitHub dependency graph · GitHub Dependabot · GitHub code security configurations
SA-22 asks two things: that unsupported components are replaced, and that alternative sources of continued support are provided for the ones that are not — in-house support, or an external provider the organization names. This plane can see the population and cannot see either answer, which is what `partial` records. An earlier draft of this note said the second limb was documented justification and approval; that is the shape of legacy baseline supplemental guidance rather than of the control, this repo's own dataset carries no guidance for SA-22 at all, and the difference matters here because the platform DOES hold a justification artifact and holds nothing whatsoever about an alternative support arrangement. Getting that wrong would have made the dismissal clause below look like it closed a limb it does not touch.
WHY THIS IS A DIFFERENT RECIPE FROM THE DEPENDENCY-VULNERABILITY ONE AND NOT A SECOND VIEW OF IT. `dependency-vulnerability-monitoring` asks whether known-vulnerable components are found and fixed; this asks whether the provider knows what it ships and whether any of it has been abandoned. The two questions overlap in their telemetry and diverge in their failure cases, and the divergence is the point: a component with no advisories at all is clean by the first question and is precisely the profile of an unmaintained package by the second, because an advisory exists when somebody researches a package and nobody researches a dead one. That is why the inventory clause rather than the alert clauses is the centre of this recipe.
THE NO-PATCH CLAUSE IS A HINT AND IS DELIBERATELY NOT WRITTEN AS A VERDICT. An open alert whose advisory carries no `first_patched_version` on any entry is the strongest end-of-support signal the documented API emits — nobody shipped a fix — and it is still not the control's finding. It is equally the shape of an advisory published hours ago, of a dispute upstream, and of a maintainer who fixed the issue without cutting a release. It is asserted because a growing set of them is a real and readable finding about the boundary, and it is described here as a hint because reading it as "these components are past end of support" would be authoring the reconciliation `scan_scope` says nobody has done.
WHAT THE DISMISSAL CLAUSE DOES AND DOES NOT ESTABLISH. `dismissed_reason` of `no_bandwidth` or `tolerable_risk` on an alert nobody can patch is the platform's record that a component was knowingly KEPT, and that is its whole value: it enumerates the components SA-22's second limb is about, which is a real service and is not the limb itself. Nothing in this output says whether in-house support was arranged for any of them or whether an external provider was named, and no field on this endpoint could. The clause is worth asserting because a dismissal carrying an empty comment is unambiguously worse than one carrying a reason, and it is worth saying plainly that passing it establishes neither replacement nor alternative support.
THE `withdrawn_at` FIELD IS COLLECTED AND NOT ASSERTED, AND THE REASON IS THE SAME ONE THAT KEEPS THE EXTERNAL-SYSTEM NOTE SHARP. An advisory can be withdrawn after this evidence was collected, which retroactively changes what a dated report meant. Nothing in the provider's system moved. It is read so a human comparing two months of this report can tell a fixed component from a withdrawn advisory, and it is not asserted because a recipe that failed on withdrawn advisories would be failing the provider for the database's corrections.
CADENCE IS `monthly` RATHER THAN `continuous`, AND THAT IS A CLAIM ABOUT THE HUMAN STEP RATHER THAN ABOUT THE PLATFORM. The alert stream underneath is continuous and the sibling recipe on SR-06 collects it that way. What SA-22 asks for is a review of an inventory against published lifecycle dates, and that reconciliation is an act somebody performs on a schedule; exporting the SBOM is the same kind of act. A provider running it continuously has not done anything wrong, and one collecting the alerts continuously while never exporting the inventory has met the sibling recipe and not this one.
KSI-SCR-MIT is the only indicator that reaches this control, and it is claimed for the identification limb of its own statement — persistently identify, review and mitigate potential supply chain risks — with the review and mitigation limbs left to the human step `scan_scope` names.