SCR — Supply Chain Risk
2 indicators, 18 controls in scope for class D; 13 of them have an authored recipe.
Class D vulnerability-response floor
VDR floor1 month
- tightest MUST
- 1 month — VDR-TFR-MVF Persistent Machine Verification and Validation for Rev5
- tightest overall
- 1 day — VDR-TFR-PSD SHOULD, so it does not bind
A response floor, not a collection interval — why
This is a class-widefloor on responding to a vulnerability, quoted in the dataset’s own units and never converted. It is not a per-check collection interval — the rules author none. Schedule against the MUST; the tightest entry may be a SHOULD.
- automatable
- partial — needs judgement
- narrative — no API proves this
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)
dailycli
$ aws configservice get-compliance-details-by-config-rule --config-rule-name ec2-managedinstance-patch-compliance-status-check --compliance-types NON_COMPLIANT$ aws ssm describe-instance-patch-states --instance-ids i-0123456789abcdef0 --query 'InstancePatchStates[].{Node:InstanceId,Baseline:BaselineId,Missing:MissingCount,Failed:FailedCount,CriticalNonCompliant:CriticalNonCompliantCount,SecurityNonCompliant:SecurityNonCompliantCount,Operation:Operation,EndTime:OperationEndTime}'$ aws inspector2 batch-get-account-status --account-ids <ACCOUNT_ID>$ aws inspector2 list-coverage --filter-criteria '{"resourceType":[{"comparison":"EQUALS","value":"AWS_EC2_INSTANCE"}]}'partialCryptographic proof that the audit trail CloudTrail delivered has not been altered or deleted, plus the compliance state of the write-once controls that make stored records and container images tamper-evident
weeklycli
$ aws configservice get-compliance-details-by-config-rule --config-rule-name cloud-trail-log-file-validation-enabled --compliance-types NON_COMPLIANT$ aws cloudtrail validate-logs --trail-arn <TRAIL_ARN> --start-time <START_TIME> --verbose$ aws configservice get-compliance-details-by-config-rule --config-rule-name s3-bucket-default-lock-enabled --compliance-types NON_COMPLIANT$ aws backup describe-backup-vault --backup-vault-name evidence-vault --query '{Locked:Locked,LockDate:LockDate,MinRetentionDays:MinRetentionDays,MaxRetentionDays:MaxRetentionDays}'$ aws configservice get-compliance-details-by-config-rule --config-rule-name ecr-private-tag-immutability-enabled --compliance-types NON_COMPLIANTpartialThe machine-generated inventory of every resource an external entity can reach — IAM Access Analyzer's active ExternalAccess findings — read against the declared zone of trust, so the terms-and-conditions review has a list to work from rather than a memory
quarterlycli
$ aws accessanalyzer list-analyzers --query 'analyzers[].{Name:name,Type:type,Status:status,Arn:arn,LastAnalyzedAt:lastResourceAnalyzedAt}'$ aws accessanalyzer list-findings-v2 --analyzer-arn <ANALYZER_ARN> --filter '{"status":{"eq":["ACTIVE"]},"findingType":{"eq":["ExternalAccess"]}}'$ aws organizations describe-organization --query 'Organization.{Id:Id,FeatureSet:FeatureSet,ManagementAccount:MasterAccountId}'$ aws configservice get-compliance-details-by-config-rule --config-rule-name iam-external-access-analyzer-enabled --compliance-types NON_COMPLIANTprovesKSI-SCR-MITKSI-IAM-ELP→AC-20
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 receives
continuouscli
$ aws health describe-events --filter eventTypeCategories=issue,accountNotification,scheduledChange$ aws sns list-subscriptions-by-topic --topic-arn <SECURITY_ALERT_TOPIC_ARN>$ aws sns get-subscription-attributes --subscription-arn <SUBSCRIPTION_ARN>provesKSI-SCR-MON→SI-05
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.
continuouscli
$ aws inspector2 batch-get-account-status$ aws ecr get-registry-scanning-configuration$ aws inspector2 list-coverage-statistics --group-by SCAN_STATUS_REASON$ aws inspector2 create-sbom-export --report-format CYCLONEDX_1_4 --s3-destination bucketName=<SBOM_BUCKET>,keyPrefix=<SBOM_PREFIX>,kmsKeyArn=<KMS_KEY_ARN>$ aws inspector2 get-sbom-export --report-id <REPORT_ID>provesKSI-SCR-MITKSI-SCR-MON→SR-05
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.
continuousapi
$ gh api --paginate "/orgs/<ORG>/code-security/configurations"$ gh api --paginate "/orgs/<ORG>/code-security/configurations/<CONFIGURATION_ID>/repositories?per_page=100"$ gh api --paginate "/orgs/<ORG>/dependabot/alerts?state=open&per_page=100"$ gh api --paginate "/orgs/<ORG>/dependabot/alerts?state=dismissed&per_page=100"$ gh api --paginate "/orgs/<ORG>/dependabot/alerts?state=auto_dismissed&per_page=100"$ gh api --paginate "/orgs/<ORG>/dependabot/alerts?state=fixed&per_page=100"provesKSI-SCR-MONKSI-SCR-MIT→SR-06
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.
continuousapi
$ gh api --paginate "/orgs/<ORG>/hooks?per_page=100"$ gh api "/orgs/<ORG>/hooks/<HOOK_ID>"$ gh api --paginate "/orgs/<ORG>/hooks/<HOOK_ID>/deliveries?status=failure&per_page=100"$ gh api --paginate "/orgs/<ORG>/hooks/<HOOK_ID>/deliveries?per_page=100"provesKSI-SCR-MON→SR-08
partialWhether static analysis is configured in this organization and which repositories it actually reaches; for each of those repositories, which query suite ran over which languages, whether the recurring schedule is still alive, when the analysis last ran and with how many rules in the run; and what the analysis found, split into what is still open and what a person closed by hand — each closure carrying who closed it, which of four fixed reasons they chose, and whatever they wrote down. The first two halves are the population and the proof that testing happened; the third is the half an assessment asks for, and read without the other two it cannot be told apart from the output of a scanner that never ran.
continuousapi
$ gh api --paginate "/orgs/<ORG>/code-security/configurations"$ gh api --paginate "/orgs/<ORG>/code-security/configurations/<CONFIGURATION_ID>/repositories?per_page=100"$ gh api "/repos/<ORG>/<REPO>/code-scanning/default-setup"$ gh api --paginate "/repos/<ORG>/<REPO>/code-scanning/analyses?tool_name=CodeQL&ref=refs/heads/<DEFAULT_BRANCH>&per_page=100"$ gh api --paginate "/orgs/<ORG>/code-scanning/alerts?state=open&tool_name=CodeQL&per_page=100"$ gh api --paginate "/orgs/<ORG>/code-scanning/alerts?state=dismissed&tool_name=CodeQL&per_page=100"provesKSI-SCR-MIT→SA-11
partialThe rules that made every change to the mainline arrive through a reviewed pull request, as a signed commit, onto a history that cannot be rewritten — together with the record of when those rules themselves last changed and who changed them, and the platform's own per-push record of any change that got past them.
weeklyapi
$ gh api --paginate "/orgs/<ORG>/repos?per_page=100"$ gh api "/repos/<ORG>/<REPO>/rules/branches/<DEFAULT_BRANCH>"$ gh api --paginate "/repos/<ORG>/<REPO>/rulesets?includes_parents=true&per_page=100"$ gh api --paginate "/repos/<ORG>/<REPO>/rulesets/<RULESET_ID>/history?per_page=100"$ gh api "/repos/<ORG>/<REPO>/rulesets/<RULESET_ID>/history/<VERSION_ID>"$ gh api --paginate "/repos/<ORG>/<REPO>/rulesets/rule-suites?ref=refs/heads/<DEFAULT_BRANCH>&time_period=month&evaluate_status=active&rule_suite_result=bypass&per_page=100"provesKSI-SCR-MIT→SA-10
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
$ gh api --paginate "/orgs/<ORG>/code-security/configurations"$ gh api --paginate "/orgs/<ORG>/code-security/configurations/<CONFIGURATION_ID>/repositories?status=attached,enforced&per_page=100"$ gh api --paginate "/orgs/<ORG>/code-security/configurations/<CONFIGURATION_ID>/repositories?per_page=100"$ gh api "/repos/<ORG>/<REPO>/dependency-graph/sbom"$ gh api --paginate "/orgs/<ORG>/dependabot/alerts?state=open&per_page=100"$ gh api --paginate "/orgs/<ORG>/dependabot/alerts?state=dismissed&per_page=100"provesKSI-SCR-MIT→SA-22
partialFor a service that ships code to a browser, the two things a pipeline can say about the mobile code it delivers: what was allowed INTO it, and whether what shipped is what this pipeline built. The first is the dependency diff for the change — every component added, its ecosystem, its version, its licence and any advisory against it, separated by whether it reaches the runtime or stops at the build — and the gate that makes the check mandatory rather than advisory. The second is a provenance attestation over the built bundle, verified against the repository and workflow that are supposed to have produced it. Neither is a statement about which mobile code technologies the organization decided to permit, and that is the control's first limb.
on-changeapi
$ gh api --paginate "/orgs/<ORG>/repos?per_page=100"$ gh api "/repos/<ORG>/<REPO>/rules/branches/<DEFAULT_BRANCH>"$ gh api "/repos/<ORG>/<REPO>/dependency-graph/compare/<BASE_SHA>...<HEAD_SHA>"$ gh attestation verify <BUNDLE_PATH> --repo <ORG>/<REPO> --signer-workflow <ORG>/<REPO>/.github/workflows/<BUILD_WORKFLOW> --format jsonprovesKSI-PIY-RSDKSI-SCR-MIT→SC-18
Indicators in this theme
- KSI-SCR-MIT12 controlsMitigating Supply Chain Risk
Persistently identify, review, and mitigate potential supply chain risks.
- KSI-SCR-MON10 controlsMonitoring 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.
No accounts — your progress ticks never leave this browser.