CMT — Change Management
4 indicators, 16 controls in scope for class D; 15 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
partialAWS Config compliance results plus the State Manager association list proving a defined configuration is actually applied and re-applied to every managed node — instances are under SSM management, and the associations that carry your baseline report COMPLIANT on a schedule rather than drifting
continuouscli
$ aws configservice get-compliance-details-by-config-rule --config-rule-name ec2-instance-managed-by-systems-manager --compliance-types NON_COMPLIANT$ aws configservice get-compliance-details-by-config-rule --config-rule-name ec2-managedinstance-association-compliance-status-check --compliance-types NON_COMPLIANT$ aws ssm list-associations --query 'Associations[].{Name:Name,AssociationId:AssociationId,Schedule:ScheduleExpression,Targets:Targets,Status:Overview.Status,LastRun:LastExecutionDate}'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"}]}'partialThe machine-maintained component inventory — Config's recorder status and discovered-resource counts proving supported resources are tracked continuously and the list stays current without anyone editing a spreadsheet, plus Systems Manager Inventory's node and installed-application metadata for what runs inside them
dailycli
$ aws configservice describe-configuration-recorder-status --query 'ConfigurationRecordersStatus[].{Name:name,Recording:recording,LastStatus:lastStatus,LastStart:lastStartTime,Error:lastErrorMessage}'$ aws configservice get-discovered-resource-counts$ aws configservice select-resource-config --expression "SELECT resourceId, resourceType, awsRegion WHERE resourceType = 'AWS::EC2::Instance'"$ aws ssm get-inventory --aggregators Expression=AWS:InstanceInformation.PlatformType$ aws ssm list-inventory-entries --instance-id i-0123456789abcdef0 --type-name AWS:ApplicationpartialWho changed what, when, and from which state to which — CloudTrail's record of every mutating API call and Config's per-resource configuration history, plus, where Change Manager is in use, the change-request executions that carry the approval
weeklycli
$ aws cloudtrail lookup-events --lookup-attributes AttributeKey=ReadOnly,AttributeValue=false --start-time <START_TIME> --end-time 2026-07-31T23:59:59Z --query 'Events[].{Event:EventName,Time:EventTime,User:Username,Source:EventSource,Resources:Resources}'$ aws configservice get-resource-config-history --resource-type AWS::EC2::SecurityGroup --resource-id sg-0123456789abcdef0 --chronological-order Reverse$ aws ssm describe-automation-executions --filters Key=AutomationSubtype,Values=ChangeRequest --query 'AutomationExecutionMetadataList[].{Id:AutomationExecutionId,Document:DocumentName,Status:AutomationExecutionStatus,Mode:Mode,By:ExecutedBy,Start:ExecutionStartTime,End:ExecutionEndTime}'partialConfig compliance results proving the ports you declared unnecessary are not reachable from the internet and the software you declared prohibited is not installed, plus the actual installed-application set a periodic review has to read
monthlycli
$ aws configservice get-compliance-details-by-config-rule --config-rule-name restricted-common-ports --compliance-types NON_COMPLIANT$ aws configservice get-compliance-details-by-config-rule --config-rule-name ec2-managedinstance-applications-blacklisted --compliance-types NON_COMPLIANT$ aws ssm list-inventory-entries --instance-id i-0123456789abcdef0 --type-name AWS:ApplicationpartialEvery running instance built from an image you never approved and every node carrying denylisted software, together with proof that an automated action was configured for those findings and a record of what it did when one fired
continuouscli
$ aws configservice get-compliance-details-by-config-rule --config-rule-name approved-amis-by-tag --compliance-types NON_COMPLIANT$ aws configservice get-compliance-details-by-config-rule --config-rule-name ec2-managedinstance-applications-blacklisted --compliance-types NON_COMPLIANT$ aws configservice describe-remediation-configurations --config-rule-names approved-amis-by-tag ec2-managedinstance-applications-blacklisted$ aws configservice describe-remediation-execution-status --config-rule-name approved-amis-by-tagpartialWhether malware scanning is switched on for compute and for the buckets that accept uploads, plus the scan-by-scan record of what was actually examined and what came back INFECTED
weeklycli
$ aws guardduty list-detectors$ aws guardduty get-detector --detector-id <DETECTOR_ID> --query '{status:Status,publishingFrequency:FindingPublishingFrequency,features:Features[].{name:Name,status:Status,additional:AdditionalConfiguration}}'$ aws guardduty describe-malware-scans --detector-id <DETECTOR_ID> --query 'Scans[].{id:ScanId,type:ScanType,status:ScanStatus,result:ScanResultDetails,started:ScanStartTime,ended:ScanEndTime,files:FileCount,bytes:TotalBytes,resource:ResourceDetails,trigger:TriggerDetails,failure:FailureReason}'$ aws guardduty list-malware-protection-plans$ aws guardduty get-malware-protection-plan --malware-protection-plan-id <PLAN_ID> --query '{protected:ProtectedResource,status:Status,statusReasons:StatusReasons,actions:Actions,role:Role,created:CreatedAt}'$ aws configservice get-compliance-details-by-config-rule --config-rule-name guardduty-malware-protection-enabled --compliance-types NON_COMPLIANTprovesKSI-CNA-DFPKSI-CMT-RMV→SI-03
partialThe enforced half of who may change what: the service control policy type actually enabled in the organization root, the customer-authored SCPs and the roots, OUs and accounts each one is attached to, and the permissions boundary carried by every principal your own tagging marks as a change authority
continuouscli
$ aws organizations describe-organization$ aws organizations list-roots$ aws organizations list-policies --filter SERVICE_CONTROL_POLICY$ aws organizations describe-policy --policy-id <CUSTOMER_AUTHORED_SCP_ID>$ aws organizations list-targets-for-policy --policy-id <CUSTOMER_AUTHORED_SCP_ID>$ aws iam get-account-authorization-details --filter User RoleprovesKSI-CMT-RMVKSI-IAM-JIT→CM-05
partialFor every change that reached the assessed branch, the automated verification that ran against it — which workflows ran, on which commit, and what each concluded — together with the two things that decide whether those runs were a condition of the change or merely adjacent to it: the rule that made the checks required, and the platform's own per-push record of whether that rule held, failed, or was bypassed. The runs alone are activity; the rule and the per-push record are what make them a gate.
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/rule-suites?ref=refs/heads/<DEFAULT_BRANCH>&time_period=month&evaluate_status=active&per_page=100"$ gh api --paginate "/repos/<ORG>/<REPO>/actions/runs?branch=<DEFAULT_BRANCH>&status=completed&per_page=100"$ gh api --paginate "/repos/<ORG>/<REPO>/actions/runs?branch=<DEFAULT_BRANCH>&status=failure&per_page=100"partialThe rule requiring the designated owners of the changed code to approve before it merges, the file that names who those owners are, the platform's own report of whether that file actually parses — and, per change, who approved, on which commit, and when.
continuousapi
$ gh api --paginate "/orgs/<ORG>/repos?per_page=100"$ gh api "/repos/<ORG>/<REPO>/rules/branches/<DEFAULT_BRANCH>"$ gh api "/repos/<ORG>/<REPO>/codeowners/errors?ref=<DEFAULT_BRANCH>"$ gh api -H "Accept: application/vnd.github.raw" "/repos/<ORG>/<REPO>/contents/.github/CODEOWNERS?ref=<DEFAULT_BRANCH>"$ gh api --paginate "/repos/<ORG>/<REPO>/pulls?state=closed&base=<DEFAULT_BRANCH>&per_page=100"$ gh api --paginate "/repos/<ORG>/<REPO>/pulls/<PULL_NUMBER>/reviews?per_page=100"Indicators in this theme
- KSI-CMT-LMC7 controlsLogging Changes
Modifications to the cloud service offering are logged and monitored.
- KSI-CMT-RMV7 controlsRedeploying vs Modifying
Changes to machine-based information resources are executed through the redeployment of version controlled resources rather than direct modification wherever reasonable.
- KSI-CMT-RVP6 controlsReviewing Change Procedures
The effectiveness of documented change management procedures is persistently reviewed.
- KSI-CMT-VTD4 controlsValidating Throughout Deployment
Persistent testing and validation of changes throughout deployment is automated.
No accounts — your progress ticks never leave this browser.