IAM — Identity and Access Management
5 indicators, 31 controls in scope for class B; 13 of them have an authored recipe.
Class B vulnerability-response floor
VDR floor7 days
- tightest MUST
- 7 days — VDR-TFR-MVX Persistent Machine Verification and Validation for 20x
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
$ aws iam generate-credential-report$ aws iam get-credential-report --query GeneratedTime --output text$ aws iam get-credential-report --query Content --output text | base64 --decode$ aws iam get-account-authorization-details --query 'UserDetailList[].{User:UserName,Groups:GroupList,Attached:AttachedManagedPolicies[].PolicyName,Inline:UserPolicyList[].PolicyName}'$ aws iam get-account-authorization-details --filter Role --query 'RoleDetailList[].{Role:RoleName,Trust:AssumeRolePolicyDocument,Attached:AttachedManagedPolicies[].PolicyName}'$ aws accessanalyzer list-analyzers --type ACCOUNT_UNUSED_ACCESS --query 'analyzers[].{arn:arn,status:status,age:configuration.unusedAccess.unusedAccessAge}'$ aws accessanalyzer list-analyzers --type ORGANIZATION_UNUSED_ACCESS --query 'analyzers[].{arn:arn,status:status,age:configuration.unusedAccess.unusedAccessAge}'$ aws accessanalyzer list-findings-v2 --analyzer-arn <UNUSED_ACCESS_ANALYZER_ARN> --filter '{"status":{"eq":["ACTIVE"]}}'$ aws configservice get-compliance-details-by-config-rule --config-rule-name mfa-enabled-for-iam-console-access --compliance-types NON_COMPLIANT$ aws configservice describe-configuration-recorder-status$ aws configservice describe-config-rule-evaluation-status --config-rule-names mfa-enabled-for-iam-console-access$ aws configservice get-compliance-details-by-config-rule --config-rule-name access-keys-rotated --compliance-types NON_COMPLIANT$ aws configservice describe-configuration-recorder-status$ aws configservice describe-config-rule-evaluation-status --config-rule-names access-keys-rotated$ aws configservice get-compliance-details-by-config-rule --config-rule-name iam-policy-no-statements-with-admin-access --compliance-types NON_COMPLIANT$ aws configservice describe-configuration-recorder-status$ aws configservice describe-config-rule-evaluation-status --config-rule-names iam-policy-no-statements-with-admin-access# aws sso-admin list-instances --query 'Instances[0].InstanceArn' --output text# aws sso-admin list-permission-sets --instance-arn <INSTANCE_ARN># aws sso-admin describe-permission-set --instance-arn <INSTANCE_ARN> --permission-set-arn <PERMISSION_SET_ARN> --query 'PermissionSet.{Name:Name,SessionDuration:SessionDuration}'# aws sso-admin list-account-assignments --instance-arn <INSTANCE_ARN> --account-id <ACCOUNT_ID> --permission-set-arn <PERMISSION_SET_ARN>The API proves RBAC structure and bounded session duration, but it cannot by itself prove that each elevation was requested, approved, and time-limited just-in-time. The approval/break-glass workflow and its evidence (tickets, approvals, deprovisioning records) are a documented process; attach the runbook and sampled approval records. Do not present the permission-set listing alone as proof of JIT.
$ aws guardduty list-detectors --query 'DetectorIds[0]' --output text$ aws guardduty list-findings --detector-id <DETECTOR_ID> --finding-criteria '{"Criterion":{"type":{"Eq":["UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS"]}}}'$ aws guardduty get-findings --detector-id <DETECTOR_ID> --finding-ids <FINDING_ID>$ aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=DeleteLoginProfile --max-results 10$ aws ssm get-document --name SSM-SessionManagerRunShell --document-version '$LATEST' --query Content --output text$ aws ssm describe-sessions --state History --query 'Sessions[].{owner:Owner,target:Target,start:StartDate,end:EndDate,document:DocumentName,accessType:AccessType,maxDuration:MaxSessionDuration}'$ aws ec2 describe-client-vpn-endpoints --query 'ClientVpnEndpoints[].{id:ClientVpnEndpointId,transport:TransportProtocol,auth:AuthenticationOptions[].Type,connectionLog:ConnectionLogOptions,splitTunnel:SplitTunnel,sessionTimeoutHours:SessionTimeoutHours,serverCert:ServerCertificateArn,selfServicePortal:SelfServicePortalUrl}'$ aws ec2 describe-client-vpn-connections --client-vpn-endpoint-id <CLIENT_VPN_ENDPOINT_ID> --query 'Connections[].{user:Username,commonName:CommonName,clientIp:ClientIp,established:ConnectionEstablishedTime,ended:ConnectionEndTime,status:Status,posture:PostureComplianceStatuses}'$ aws configservice get-compliance-details-by-config-rule --config-rule-name ec2-instance-no-public-ip --compliance-types NON_COMPLIANT$ aws iam get-account-summary --query 'SummaryMap.{Users:Users,Providers:Providers,MFADevices:MFADevices,MFADevicesInUse:MFADevicesInUse,AccountAccessKeysPresent:AccountAccessKeysPresent,AccountSigningCertificatesPresent:AccountSigningCertificatesPresent}'$ aws iam list-saml-providers --query 'SAMLProviderList[].{Arn:Arn,ValidUntil:ValidUntil,CreateDate:CreateDate}'$ aws iam list-open-id-connect-providers$ aws sso-admin list-instances --query 'Instances[].{InstanceArn:InstanceArn,IdentityStoreId:IdentityStoreId,Status:Status}'$ aws configservice get-compliance-details-by-config-rule --config-rule-name iam-user-mfa-enabled --compliance-types NON_COMPLIANT$ aws configservice get-compliance-details-by-config-rule --config-rule-name iam-root-access-key-check --compliance-types NON_COMPLIANT$ aws cognito-idp list-user-pools --max-results 60 --query 'UserPools[].{Id:Id,Name:Name,Status:Status}'$ aws cognito-idp get-user-pool-mfa-config --user-pool-id <USER_POOL_ID>$ aws cognito-identity list-identity-pools --max-results 60 --query 'IdentityPools[].{Id:IdentityPoolId,Name:IdentityPoolName}'$ aws cognito-identity describe-identity-pool --identity-pool-id <IDENTITY_POOL_ID> --query '{Id:IdentityPoolId,AllowUnauthenticatedIdentities:AllowUnauthenticatedIdentities,AllowClassicFlow:AllowClassicFlow,Cognito:CognitoIdentityProviders,Login:SupportedLoginProviders,Saml:SamlProviderARNs,Oidc:OpenIdConnectProviderARNs}'$ aws iam list-roles --query 'Roles[].{Role:RoleName,MaxSessionDuration:MaxSessionDuration}'$ aws sso-admin list-instances --query 'Instances[].InstanceArn'$ aws sso-admin list-permission-sets --instance-arn <INSTANCE_ARN>$ aws sso-admin describe-permission-set --instance-arn <INSTANCE_ARN> --permission-set-arn <PERMISSION_SET_ARN> --query 'PermissionSet.{Name:Name,SessionDuration:SessionDuration}'$ aws iam get-account-authorization-details --query '{Managed:Policies[].PolicyVersionList[?IsDefaultVersion].Document,UserInline:UserDetailList[].UserPolicyList[].PolicyDocument,RoleInline:RoleDetailList[].RolePolicyList[].PolicyDocument,GroupInline:GroupDetailList[].GroupPolicyList[].PolicyDocument}'$ aws configservice describe-config-rules --config-rule-names iam-user-unused-credentials-check$ aws configservice get-compliance-details-by-config-rule --config-rule-name iam-user-unused-credentials-check --compliance-types NON_COMPLIANT$ aws configservice describe-remediation-configurations --config-rule-names iam-user-unused-credentials-check$ aws iam get-account-authorization-details --filter User$ 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_COMPLIANT$ 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 Role$ aws iam get-account-authorization-details --filter User Role Group$ aws sso-admin list-instances$ aws identitystore list-users --identity-store-id <IDENTITY_STORE_ID>$ aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=DeleteUser --start-time <T0> --end-time <T1>$ aws iam generate-credential-report$ aws iam get-credential-report$ aws identitystore list-users --identity-store-id <IDENTITY_STORE_ID>$ aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=DeleteUser --start-time <T0> --end-time <T1>$ aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=DeleteLoginProfile --start-time <T0> --end-time <T1>$ aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=DeleteAccessKey --start-time <T0> --end-time <T1>$ aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=UpdateAccessKey --start-time <T0> --end-time <T1>$ aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=DeactivateMFADevice --start-time <T0> --end-time <T1>$ aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=AddUserToGroup --start-time <T0> --end-time <T1>$ aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=RemoveUserFromGroup --start-time <T0> --end-time <T1>$ aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=AttachUserPolicy --start-time <T0> --end-time <T1>$ aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=DetachUserPolicy --start-time <T0> --end-time <T1>$ aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=CreateAccountAssignment --start-time <T0> --end-time <T1>$ aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=DeleteAccountAssignment --start-time <T0> --end-time <T1>$ aws sso-admin list-permission-sets --instance-arn <INSTANCE_ARN>$ aws sso-admin list-account-assignments --instance-arn <INSTANCE_ARN> --account-id <ACCOUNT_ID> --permission-set-arn <PERMISSION_SET_ARN>$ aws iam generate-service-last-accessed-details --arn <PRINCIPAL_ARN> --granularity ACTION_LEVEL$ aws iam get-service-last-accessed-details --job-id <JOB_ID>Indicators in this theme
- KSI-IAM-APM13 controlsAdopting Passwordless Methods
Secure passwordless methods are used for user authentication and authorization when feasible, otherwise strong passwords with phishing-resistant MFA is used.
- KSI-IAM-ELP34 controlsEnsuring Least Privilege
Identity and access management measures are used and persistently reviewed to ensure each user or device can only access the resources they need.
- KSI-IAM-JIT38 controlsAuthorizing Just-in-Time
A least-privileged, role and attribute-based, and just-in-time security authorization model is used and persistently reviewed for all user and non-user accounts and services.
- KSI-IAM-SNU7 controlsSecuring Non-User Authentication
Appropriately secure authentication methods are used and persistently reviewed for non-user accounts and services.
- KSI-IAM-SUS7 controlsResponding to Suspicious Activity
Accounts with privileged access are disabled or otherwise secured in response to suspicious activity.