KSI-SCR-MONMonitoring Supply Chain Risk
Third party software information resources are automatically monitored for upstream vulnerabilities using mechanisms that may include contractual notification requirements or active monitoring services.
Mapped NIST 800-53 controls (10)
- recipe7
- KSI only3
The mark says whether an authored AWS recipe fetches evidence for the control; the tier strip shows which Rev5 baselines also require it — where automated KSI evidence doubles as Rev5 control evidence. = in the class B, C and D baselines, left to right
- recipe— an authored recipe collects evidence for this control
- KSI only— a Key Security Indicator reaches it, but no recipe is authored yet
- orphan— no Key Security Indicator reaches it — a person writes it up instead
- recipe · 1 recipeAC-20ACIn baseline B, C, D
- KSI onlyCA-03CAIn baseline B, C, D
- recipe · 1 recipeIR-06 (03)IRIn baseline C, D
- KSI onlyPS-07PSIn baseline B, C, D
- recipe · 1 recipeRA-05RAIn baseline B, C, D
- KSI onlySA-09SAIn baseline B, C, D
- recipe · 1 recipeSI-05SIIn baseline B, C, D
- recipe · 1 recipeSR-05SRIn baseline B, C, D
- recipe · 1 recipeSR-06SRIn baseline C, D
- recipe · 1 recipeSR-08SRIn baseline B, C, D
Collect evidence (5)
Authored AWS and pipeline recipes whose output is evidence for KSI-SCR-MON. This mapping is this project’s opinion (AWS overlay v3.0.0, pipeline overlay v0.8.0), versioned separately from the dataset — the upstream FedRAMP rules name none of these tools.
- partialPatch Manager compliance state plus Amazon Inspector scan status and coverage — proving flaws are being found continuously (Inspector enabled and actually covering your resources) and that the fixes landed (per-node missing/failed patch counts and the time of the last scan or install)dailycliawspatch-and-vulnerability-remediationAWS Config · AWS Systems Manager Patch Manager · Amazon Inspector
This proves flaws are detected and shows exactly what is still missing and when patching last ran — it does not prove the remediation clock was met. Whether an open finding sits inside your SI-02 timeframe, or carries an approved deviation or POA&M entry, is a judgement joined against your risk-acceptance record, not an API result. Substitute your real instance ids and account id; describe-instance-patch-states requires --instance-ids (use describe-instance-patch-states-for-patch-group to sweep a patch group). Note also that patch compliance data is a point-in-time snapshot and each successful scan overwrites the previous one, so capture the output at collection time rather than reconstructing history later.
- partialThe advisories AWS itself has issued against this account — operational issues, scheduled changes and account notifications, each dated and scoped — together with the subscribers on the topic those alerts are published to and the confirmation state of each subscription, which is the difference between an address that was entered and an address that receivescontinuouscliawssecurity-advisories-receipt-and-disseminationAWS Health · Amazon SNS
SI-05 has four movements: receive security alerts, advisories and directives from external organizations on an ongoing basis; generate internal security alerts; disseminate them to the personnel your policy names; and implement directives or notify the issuing organization of the degree of nonconformance. This output touches the first and the third, and only for one external organization. That organization is AWS. Health events are the vendor's own notifications to this account — operational issues, scheduled changes, account notifications — dated, scoped by eventScopeCode to this account or to the service generally, and enumerable. That is a real answer to 'are you receiving advisories from your suppliers, on an ongoing basis, and can you show it'. The supply-chain indicator is claimed on one limb of its statement and not the whole: KSI-SCR-MON allows for mechanisms that 'may include contractual notification requirements', and a vendor health feed is exactly such a mechanism. It is NOT the other limb — none of Health's four event categories is a vulnerability category, and this evidence monitors AWS's service health rather than the provider's third-party software inventory. Read the claim as the notification limb only. What it is not is the control. CISA emergency directives, US-CERT advisories, vendor bulletins for every other component in the stack, and the entire question of implementing a directive or reporting nonconformance to the issuer are correspondence and decisions. No API returns them, and a collection that presents Health events as SI-05 evidence without saying which limb they serve has answered a quarter of a control. The dissemination half is where the honest telemetry is, and it is smaller than it looks. A topic with subscribers proves an alert has somewhere to go. It does not prove the subscribers are the personnel the policy names — that is a roster comparison — and it does not prove they receive anything unless the subscription is CONFIRMED. AWS requires confirmation for HTTP(S) endpoints, email addresses and cross-account resources. The unconfirmed case is visible, and it is visible in the place you would not look for it. An unconfirmed subscription appears in the topic's subscription list with SubscriptionArn set to the literal string PendingConfirmation instead of an ARN — not a missing field, not a flag, a sentinel value in the identifier column. So the completeness clause below is written against the LIST. An earlier draft asserted the PendingConfirmation attribute from get-subscription-attributes instead, which cannot work: that call takes --subscription-arn, the unconfirmed subscription has no ARN to pass, and the failing case therefore never reaches the assertion at all. The third call stays as supplementary evidence for ConfirmationWasAuthenticated, which the list genuinely does not carry, and it carries no clause. If a clause is ever written on those attributes, note that they come back as a map of STRINGS — PendingConfirmation is "true" or "false", not a boolean, and a comparison against a boolean matches nothing while returning green. One gap the assertions cannot see, named here because a partial rating owes it: nothing collected joins the Health feed to the topic. SECURITY_ALERT_TOPIC_ARN is supplied by the operator, and no output here shows an EventBridge rule on the aws.health source targeting it. The two halves of this recipe are adjacent in the assessment's head and unjoined in the data; collect the EventBridge rule and its targets if that join needs to be evidence rather than assertion. Two emptiness traps. describe-events as written sets no time bound — the filter selects categories, not a window — so what comes back is what AWS Health currently holds, and an empty events[] means the same thing on an account receiving advisories perfectly as on one whose Health access was never wired up. Add startTimes to the filter if the assessment needs the evidence pinned to a period. And the third call must be repeated per subscription: one confirmed subscription proves nothing about the other nine, and the assertion below is written against a single subscription ARN because that is what the API takes — walk the list from the second call and collect one response each, or the evidence covers one address. KSI-SVC-ACM was deliberately not claimed. It asks that configuration be managed by automation and reviewed for drift; an advisory feed and a subscriber list say nothing about configuration, and claiming it would put this recipe on an indicator page as evidence for a question it never asks.
- partialWhether the tooling that examines acquired software is switched on and covering the estate, and what it found: Inspector's per-account enablement state for each scanned resource type, the registry-wide ECR scanning configuration (scan type and frequency, and the repository filters that decide which repositories it applies to), Inspector's own coverage statistics, and a CycloneDX 1.4 or SPDX 2.3 SBOM exported per monitored resource — the component-level inventory of what was actually acquired.continuouscliawsacquisition-scanning-and-sbom-inventoryAmazon Inspector · Amazon ECR
SR-05 asks for acquisition strategies, contract tools and procurement methods that reduce supply-chain risk. Two halves, and AWS holds one of them completely and the other not at all. The half it holds is the TOOLING at the moment of acquisition. ECR's registry scanning configuration is the acquisition gate: scan-on-push examines an image as it enters the registry, and the rules[] with their repository filters say which repositories that applies to. Inspector monitors what has already landed and exports an SBOM per resource, which is the component-level inventory of what was actually acquired rather than what a supplier said they shipped. Both are continuous, both are machine-readable, and together they answer 'what did we take in, and what was wrong with it'. The half it does not hold is the STRATEGY the control names — the contract clauses, the approved-supplier list, the delivery method, the decision to buy this component rather than that one. No scanner stands in for procurement, and none of these five commands reads a contract. That is the whole reason for the partial rating, and the assessment reads it out of the acquisition documentation the control asks for. The enablement and coverage calls exist because of the empty-list trap, and here it is unusually sharp. A findings query against an estate with Inspector switched off returns an empty array and exits zero, and so does a clean estate. batch-get-account-status is what separates them: it reports status per resource type, so ECR ENABLED with EC2 DISABLED is visible as the partial coverage it is rather than as silence. Read BOTH of its arrays. An account that could not be enabled — access denied, or blocked by an Organizations policy — is reported in failedAccounts[] and does not appear in accounts[] at all, so a clause over accounts[] alone is green on the one account whose scanning never began. The enumeration has an edge worth stating too: accounts[] is capped at one hundred entries with no continuation token, and what the call returns when no account ids are passed is undocumented — so run it as the delegated administrator with the ids you mean, and treat the response as evidence about the accounts it names rather than about the organization. list-coverage-statistics closes the second half of the same gap — Inspector can be enabled and still not be covering a resource, and a count of covered resources is the denominator every finding count needs. Neither is decoration; without them the SBOM evidence is a claim about an unknown population. The registry configuration has its own version of the trap, and it is the reason no assertion here asserts on rules[] alone. Scan frequency defaults to MANUAL where scan-on-push was not configured, and a registry with NO rules is a registry that scans nothing on push — but it answers with a well-formed scanningConfiguration all the same, so a clause reading 'every rule has SCAN_ON_PUSH or CONTINUOUS_SCAN' is vacuously true on exactly the estate that has configured nothing. The offender form is the population of repositories no rule's filter matches, and that needs a join against describe-repositories this assertion grammar cannot express — which is why this is partial and not full even though the enablement half could be written down. On the SBOM export: it needs an S3 bucket whose policy allows Inspector to write and a KMS key whose policy allows Inspector to encrypt, both configured before the call, and it is asynchronous — create returns a reportId and get reports status. Read the unresolved-hash note in the output as evidence rather than noise. A component whose package manager used a version range cannot be mapped to a name and version, and therefore cannot be scanned for vulnerabilities at all; Inspector now includes those hashes in the export. They are the components a vulnerability count does not cover, and an SBOM read without them looks cleaner than the estate is. KSI-SCR-MON is earned directly: third-party software resources ARE automatically monitored for upstream vulnerabilities, and these commands prove the mechanism is on and covering. KSI-SCR-MIT is claimed for identify-and-review and not for mitigate — nothing here shows a risk being closed, only found.
- partialWhether Dependabot alerting is configured in this organization and which repositories it actually reaches, together with the alerts themselves — each carrying the advisory that raised it, the package, ecosystem and manifest path it was found in, the reason a human gave for closing it, and, for a remediated one, the date it was fixed. The first half is the population; the second half is what was found in it, and the second half means nothing without the first.continuousapipipelinedependency-vulnerability-monitoringGitHub Dependabot · GitHub code security configurations
SR-06 asks the provider to ASSESS AND REVIEW the supply chain risk associated with suppliers and contractors. This output assesses one population — the third-party software components resolved into the build — continuously, and it produces a reviewable record for each finding. That is a real answer to one limb and it is not the control. Provenance, contract terms, geographic and financial exposure, and the frequency at which a supplier is re-reviewed are a human record, and a manifest entry names a package, not a supplier's risk posture. The disposition this recipe spends said exactly that, and the rating is unchanged by having written the commands down. What the population is, and what it is not. GitHub documents that when Dependabot alerts are enabled it "immediately generates the dependency graph and creates alerts for any vulnerable dependencies it identifies", so the graph is not a separate switch a clause below needs to police — which is why the first assertion reads `dependabot_alerts` and not both fields. What the same page says under its own heading of limitations, and what bounds this recipe more than anything else in it, is that "only advisories reviewed by GitHub trigger alerts". The detection surface is the GitHub Advisory Database's reviewed set. A vulnerability that is real, published, and not in that set produces no alert, and an empty list is silent about it. A second, sharper limit sits inside the first: alerting on MALICIOUS packages, as opposed to vulnerable ones, is a separate opt-in that has to be enabled after Dependabot alerts are, and no command in this recipe can see whether it is on — the code security configuration response carries no property for it. So an alert list with no malware finding in it is equally an organization with no malicious dependency and an organization that never switched the detection on, and a clause asserting the absence of malware would be vacuous for exactly that reason. Both limits are ceilings on the evidence rather than defects in the collection, and they belong in the assessment rather than in a footnote. A code security configuration is not the only way Dependabot gets switched on, and the first clause below is wrong in one direction because of it. Alerts can be enabled on a repository directly, in that repository's own settings, with no configuration involved. An organization that never adopted configurations therefore returns an empty list from the first command and FAILS the clause while scanning every repository it owns. Read a failure there as "no organization-level configuration governs this", which is a real and useful finding, and NOT as "nothing is scanned" — the second reading is unsupported and the reconciliation named in `scan_scope` is what distinguishes them. The multi-configuration case, named because the first assertion is weaker than it reads in the other direction too. The clause is satisfied by ANY qualifying configuration, including one applied to no repository at all. The `target_type` narrowing on both configuration clauses is a deliberate trade and it costs something. The enum admits `global` and `enterprise` alongside `organization`, and GitHub ships a recommended configuration that an administrator does not create but DOES apply from the organization's own configurations table — applying it is a decision, and a decision this clause will not count. So the narrowing buys a false FAIL on GitHub's recommended path and on an enterprise-applied one, in exchange for not passing on a row the organization never chose. That is the right way round only because of how a failure is to be read, below: not as "nothing is scanned" but as "no configuration this organization owns governs this", which is literally true in the global and enterprise cases too. What documentation does NOT settle is whether the org endpoint returns those rows at all — its description says configurations "available in" an organization rather than owned by one — and the live risk is not that the narrowing is unnecessary but that the rows it excludes are the organization's real answer. One call against a live organization settles it, and an assessment leaning on either configuration clause should make that call first. Why there is no clause on `dismissed_reason`. An earlier draft asserted that no dismissed alert had a null reason, and it was decorative: GitHub requires a `dismissed_reason` when an alert's state is set to `dismissed`, so on a `state=dismissed` list there is no documented path that yields null and the clause could not fail. It is recorded here so it is not re-added. The review limb of the claim rests on the fourth command's output being collected and read, not on a check that cannot go red. `state=dismissed`, `state=auto_dismissed` and `state=fixed` are three separate queries, and the last two carry no assertion deliberately. The auto-dismissed list exists because an organization whose alerts close mostly by rule has a short `dismissed` list, and any review clause would be near-vacuously true while very little was reviewed by anyone; an auto-dismissal is a rule firing, not a person deciding, and a clause about its count would assert that a policy is correct rather than that a review happened. The fixed list exists because it is the mitigation record, and it is the reason KSI-SCR-MIT can be claimed at all — but a count of remediated alerts is a measure of how much was broken, not of how well it was handled, and no threshold over it would mean anything without the response clock the plan surfaces separately. It carries the emptiness problem the open list carries, and it carries it while bearing the whole weight of the mitigation claim: an empty fixed list is equally an organization that has never had a vulnerable dependency, one that has never remediated one, and one whose scanning was switched on last week. Nothing in this recipe distinguishes those, which is why the claim on that indicator is a collected record for a human to read and not a check that can go red. MAS-CSO-TPR was deliberately not claimed, and the reasoning is recorded so the next batch does not re-derive it. Its artifact is a machine-readable output of the third-party information resources of the offering, and a dependency IS a third-party information resource on the dataset's own definition — an information resource not entirely inside the Minimum Assessment Scope, where information resources expressly include software and code. But the requirement's statement names the data that output must carry: general usage and configuration, an explanation or justification for use, mitigation measures, and compensating controls. An alert stream carries none of the four, and the enumeration it implies is a by-product rather than the artifact. A recipe that exported the dependency graph SBOM would have a genuine partial claim on that requirement; this one does not, and adjacency is not a join. KSI-SCR-MIT is claimed on the software-component limb only. Identify is the alert, review is `dismissed_reason`, mitigate is the transition to `fixed` — those three are the indicator's three verbs, over one supplier population, and all three are now collected rather than two of them being collected and the third described. Hardware, managed services, and every supplier relationship that never resolves into a manifest are outside it, and an indicator page carrying this recipe should be read as carrying evidence for a part. The evidence platform is itself an external system; see `external_system`. It is not a footnote on this control in particular — SR-06 is a supply chain control, and answering it by adopting a supplier is a move that has to be visible in the assessment rather than only in the recipe.
- partialThe organization's webhook configuration — which endpoints are subscribed to the supply-chain alert event, whether each is switched on, and where it points — together with the platform's own record of what it actually delivered to them and with what response code. Configuration says a path exists; the delivery log says the path carried something.continuousapipipelinesupply-chain-alert-notification-routingGitHub webhooks · GitHub Dependabot
SR-08 establishes agreements and procedures with entities in the supply chain for notification of compromise or of a vulnerability. It has two limbs and this recipe answers one of them. The agreements limb is a contract with a supplier and nothing here touches it. What this recipe deliberately does NOT read is the alert list, and that is the whole design. A public advisory feed is not an entity in your supply chain, so an alert stream — however rich — cannot evidence SR-08 on its own; the feed itself is SI-05's artifact and is already collected there. What is evidence is the procedure: that an upstream notification, once it arrives, is delivered to a named destination rather than into nothing. That is configuration plus a delivery record, which is what these commands collect. A future batch tempted to strengthen this recipe by adding `dependabot/alerts` to it should read this paragraph first. The emptiness trap here is worse than usual and it is worth being blunt about. GitHub's deliveries reference documents `per_page`, `cursor` and a `status` filter, and states NO retention period for delivery records. So the window these commands read is of unknown length, and an empty deliveries list means one of: nothing was ever delivered, nothing has been delivered recently, or nothing is retained that far back. None of the three is distinguishable from the others in the output, and none of them is a pass. The failure clause below is therefore written over the `status=failure` list — a list whose emptiness is meaningful in a way the full list's is not, because it is built to contain offenders — and the fourth command is collected as the corroborating record a human reads for volume and recency. No clause asserts the full list is non-empty, because on a quiet organization it legitimately is. The wildcard is in BOTH hook clauses rather than in a note, and it has to be in both. A hook created with `events: [\"*\"]` receives every event including this one and may contain the string `dependabot_alert` nowhere, so a clause matching the literal alone reports the most completely subscribed configuration on the platform as unsubscribed. An earlier draft carried the disjunct on the first clause and not the second, which was worse than omitting it from both: the second clause exists to catch a subscribed-but-disabled hook, and without the disjunct the hook it could not see was exactly the wildcard one that had been switched off. Note also that GitHub documents the wildcard on the create request body; nothing states what a GET returns for such a hook, so the disjunction is written to be correct whether the literal survives the round trip or is expanded. The deprecated event, which no clause tests and every assessment should look for. GitHub carries a closing-down notice on `repository_vulnerability_alert` — "this event is closing down, use the `dependabot_alert` event instead" — with actions `create`, `dismiss`, `reopen` and `resolve`. An organization whose only subscription is that event is being delivered to today and is on a path that ends. It fails the first clause below, and that failure is correct rather than a false positive: the finding is real, its severity is scheduled rather than immediate, and reading the failure as a configuration error would be reading it right for the wrong reason. Organization hooks are not the only hooks. `dependabot_alert` is available on repository, organization and app webhooks, and `/orgs/{org}/hooks` returns only the middle one. A provider routing alerts per repository, or through a GitHub App, has a correct configuration that is entirely absent from these commands. That is a scope limit rather than a finding, and an assessment that reads an empty org hooks list as a failure has misread it — walk the repositories in the boundary, or the app installation, and collect the same two calls there. What a delivery proves and where it stops. A `status_code` in the 200–399 band says the platform reached an endpoint and the endpoint accepted the payload. It does not say the payload was parsed, was routed onward, reached a person, or was acted on within any clock. Every one of those is the thing SR-08's procedures limb ultimately cares about, and every one of them lives in the receiving system rather than in this one — which is the honest reason this recipe is `partial` and would still be `partial` with a perfect delivery log. KSI-SCR-MIT was deliberately not claimed. The dataset reaches SR-08 from KSI-SCR-MON alone, and a routing path evidences monitoring reaching someone rather than a risk being identified, reviewed and mitigated.
Default evidence owed by every indicator (5)
From info.default_artifacts.KSI — no indicator carries its own artifacts; requirement-specific evidence lives on /evidence.
- Explanation of measures (and their objectives) that demonstrate the Key Security Indicator, or an explanation of the reason and resulting risk to customers for not having measures available for that Key Security Indicator.
- Explanation of the cycle for any measures that are implemented persistently (if applicable).
- Verification that the measures demonstrate the Key Security Indicator, or that the reason for not having them is accepted.
- Verification that the automation in place is accurate and sufficient to demonstrate appropriate measures for the Key Security Indicator, or that automation is not necessary for each measure.
- Validation that the measures are accurately produced and are in place and working as intended, or that the reason for not having them is valid.
Defined terms used (2)
- Information Resource
- Has the meaning from 44 USC § 3502 (6): "information and related resources, such as personnel, equipment, funds, and information technology." This includes any aspect of the cloud service offering, both technical and managerial, including everything that makes up the business of the offering from non-machine-based information resources like organizational policies, procedures, employees, etc. to machine-based information resources like hardware, software, cloud services, code, etc.
- Vulnerability
- Has the meaning given to "security vulnerability" in 6 USC § 650 (25), which is "any attribute of hardware, software, process, or procedure that could enable or facilitate the defeat of [...] management, operational, and technical controls used to protect against an unauthorized effort to adversely affect the confidentiality, integrity, and availability of an information system or its information." This includes gaps in Rev5 Controls and 20x Key Security Indicators, software vulnerabilities, misconfigurations, exposures, weak credentials, insecure services, and all other such potential weaknesses in protection (intentional or unintentional).
The Supply Chain Risk run (2)
2/2 have an authored AWS recipe- 8 authored recipesKSI-SCR-MITMitigating Supply Chain Risk
- 5 authored recipesKSI-SCR-MONMonitoring Supply Chain Riskyou are here