Guided Walkthroughs

Configuration Packages

Custom Packages

By Implementation

Service Control PoliciesConfig RulesAuto Remediation RulesConformance PacksAmazon GuardDutyAmazon InspectorAWS Security HubAWS Network FirewallRoute53 Resolver SecurityAmazon MacieS3 Bucket PoliciesCloudWatch Alarms and Event RulesAWS WAFAWS Secrets ManagerAWS Systems ManagerSecurity Groups & NACLsAWS KMSAWS SSOIAM PoliciesVPC Endpoint PoliciesCloudFormation Guard RulesLoad BalancersRDS Event SubscriptionsAWS Resource Access Manager (RAM)

By Service Protected

Reference Guides

Other

CloudFormation Guard Rules

CloudFormation Guard Rules Package

A configuration package to create a custom CloudFormation Guard rules template. The package includes 150+ rules across most AWS services including EC2, S3, IAM, and many more.

Select the relevant AWS services to enable the relevant CloudFormation Guard rules. You can then edit each service to customize which rules to include in the final template

A premium subscription is required for this content
You can browse all CloudFormation Guard Rules for individual AWS services in our repository for free! Go to Library


let iam_groups = Resources.*[
	Type == "AWS::IAM::Group"
]

let iam_roles = Resources.*[
	Type == "AWS::IAM::Role"
]

let iam_users = Resources.*[
	Type == "AWS::IAM::User"
]

let iam_policies = Resources.*[
	Type == "AWS::IAM::Policy"
]

let iam_managedpolicies = Resources.*[
	Type == "AWS::IAM::ManagedPolicy"
]

rule iam_policy_full_admin when %iam_groups !empty OR %iam_roles !empty OR %iam_users !empty OR %iam_policies !empty OR %iam_managedpolicies !empty{
	when %iam_groups !empty {
		%iam_groups {
			Properties {
				when Policies exists {
					Policies.* {
						PolicyDocument {
							Statement.*[
								Effect == "Allow"
								some Action[*] == "*"
								some Resource[*] == "*"
							] empty <<IAM group were found with a policy that allows full administrator permissions '*:*>>
						}
					}
				}
			}
		}
	}
	
	when %iam_roles !empty {
		%iam_roles {
			Properties {
				when Policies exists {
					Policies.* {
						PolicyDocument {
							Statement.*[
								Effect == "Allow"
								some Action[*] == "*"
								some Resource[*] == "*"
							] empty <<IAM role found with a policy that allows full administrator permissions '*:*>>
						}
					}
				}
			}
		}
	}

	when %iam_users !empty {
		%iam_users {
			Properties {
				when Policies exists {
					Policies.* {
						PolicyDocument {
							Statement.*[
								Effect == "Allow"
								some Action[*] == "*"
								some Resource[*] == "*"
							] empty <<IAM user found with a policy that allows full administrator permissions '*:*>>
						}
					}
				}
			}
		}
	}

	when %iam_policies !empty {
		%iam_policies {
			Properties {
				PolicyDocument {
					Statement.*[
						Effect == "Allow"
						some Action[*] == "*"
						some Resource[*] == "*"
					] empty <<IAM policy found that allows full administrator permissions '*:*>>
				}
			}
		}
	}

	when %iam_managedpolicies !empty {
		%iam_managedpolicies {
			Properties {
				PolicyDocument {
					Statement.*[
						Effect == "Allow"
						some Action[*] == "*"
						some Resource[*] == "*"
					] empty <<IAM managed policy found that allows full administrator permissions '*:*>>
				}
			}
		}
	}
}

rule iam_policy_sts_assume when %iam_groups !empty OR %iam_roles !empty OR %iam_users !empty OR %iam_policies !empty OR %iam_managedpolicies !empty{
	when %iam_groups !empty {
		%iam_groups {
			Properties {
				when Policies exists {
					Policies.* {
						PolicyDocument {
							Statement.*[
								Effect == "Allow"
								some Action[*] == "sts:AssumeRole"
								some Resource[*] == "*"
							] empty <<IAM group were found with a policy that allows unrestricted sts:AssumeRole>>
						}
					}
				}
			}
		}
	}
	
	when %iam_roles !empty {
		%iam_roles {
			Properties {
				when Policies exists {
					Policies.* {
						PolicyDocument {
							Statement.*[
								Effect == "Allow"
								some Action[*] == "sts:AssumeRole"
								some Resource[*] == "*"
							] empty <<IAM role found with a policy that allows unrestricted sts:AssumeRole>>
						}
					}
				}
			}
		}
	}

	when %iam_users !empty {
		%iam_users {
			Properties {
				when Policies exists {
					Policies.* {
						PolicyDocument {
							Statement.*[
								Effect == "Allow"
								some Action[*] == "sts:AssumeRole"
								some Resource[*] == "*"
							] empty <<IAM user found with a policy that allows unrestricted sts:AssumeRole>>
						}
					}
				}
			}
		}
	}

	when %iam_policies !empty {
		%iam_policies {
			Properties {
				PolicyDocument {
					Statement.*[
						Effect == "Allow"
						some Action[*] == "sts:AssumeRole"
						some Resource[*] == "*"
					] empty <<IAM policy found that allows unrestricted sts:AssumeRole>>
				}
			}
		}
	}

	when %iam_managedpolicies !empty {
		%iam_managedpolicies {
			Properties {
				PolicyDocument {
					Statement.*[
						Effect == "Allow"
						some Action[*] == "sts:AssumeRole"
						some Resource[*] == "*"
					] empty <<IAM managed policy found that allows unrestricted sts:AssumeRole>>
				}
			}
		}
	}
}

rule iam_policy_iam_passrole when %iam_groups !empty OR %iam_roles !empty OR %iam_users !empty OR %iam_policies !empty OR %iam_managedpolicies !empty{
	when %iam_groups !empty {
		%iam_groups {
			Properties {
				when Policies exists {
					Policies.* {
						PolicyDocument {
							Statement.*[
								Effect == "Allow"
								some Action[*] == "iam:PassRole"
								some Resource[*] == "*"
							] empty <<IAM group were found with a policy that allows unrestricted iam:PassRole>>
						}
					}
				}
			}
		}
	}
	
	when %iam_roles !empty {
		%iam_roles {
			Properties {
				when Policies exists {
					Policies.* {
						PolicyDocument {
							Statement.*[
								Effect == "Allow"
								some Action[*] == "iam:PassRole"
								some Resource[*] == "*"
							] empty <<IAM role found with a policy that allows unrestricted iam:PassRole>>
						}
					}
				}
			}
		}
	}

	when %iam_users !empty {
		%iam_users {
			Properties {
				when Policies exists {
					Policies.* {
						PolicyDocument {
							Statement.*[
								Effect == "Allow"
								some Action[*] == "iam:PassRole"
								some Resource[*] == "*"
							] empty <<IAM user found with a policy that allows unrestricted iam:PassRole>>
						}
					}
				}
			}
		}
	}

	when %iam_policies !empty {
		%iam_policies {
			Properties {
				PolicyDocument {
					Statement.*[
						Effect == "Allow"
						some Action[*] == "iam:PassRole"
						some Resource[*] == "*"
					] empty <<IAM policy found that allows unrestricted iam:PassRole>>
				}
			}
		}
	}

	when %iam_managedpolicies !empty {
		%iam_managedpolicies {
			Properties {
				PolicyDocument {
					Statement.*[
						Effect == "Allow"
						some Action[*] == "iam:PassRole"
						some Resource[*] == "*"
					] empty <<IAM managed policy found that allows unrestricted iam:PassRole>>
				}
			}
		}
	}
}

rule iam_policy_s3_allaccess when %iam_groups !empty OR %iam_roles !empty OR %iam_users !empty OR %iam_policies !empty OR %iam_managedpolicies !empty{
	when %iam_groups !empty {
		%iam_groups {
			Properties {
				when Policies exists {
					Policies.* {
						PolicyDocument {
							Statement.*[
								Effect == "Allow"
								some Action[*] == "s3:*"
								some Resource[*] == "*"
							] empty <<IAM group were found with a policy that allows unrestricted s3:*>>
						}
					}
				}
			}
		}
	}
	
	when %iam_roles !empty {
		%iam_roles {
			Properties {
				when Policies exists {
					Policies.* {
						PolicyDocument {
							Statement.*[
								Effect == "Allow"
								some Action[*] == "s3:*"
								some Resource[*] == "*"
							] empty <<IAM role found with a policy that allows unrestricted s3:*>>
						}
					}
				}
			}
		}
	}

	when %iam_users !empty {
		%iam_users {
			Properties {
				when Policies exists {
					Policies.* {
						PolicyDocument {
							Statement.*[
								Effect == "Allow"
								some Action[*] == "s3:*"
								some Resource[*] == "*"
							] empty <<IAM user found with a policy that allows unrestricted s3:*>>
						}
					}
				}
			}
		}
	}

	when %iam_policies !empty {
		%iam_policies {
			Properties {
				PolicyDocument {
					Statement.*[
						Effect == "Allow"
						some Action[*] == "s3:*"
						some Resource[*] == "*"
					] empty <<IAM policy found that allows unrestricted s3:*>>
				}
			}
		}
	}

	when %iam_managedpolicies !empty {
		%iam_managedpolicies {
			Properties {
				PolicyDocument {
					Statement.*[
						Effect == "Allow"
						some Action[*] == "s3:*"
						some Resource[*] == "*"
					] empty <<IAM managed policy found that allows unrestricted s3:*>>
				}
			}
		}
	}
}

rule iam_policy_iam_sensitive when %iam_groups !empty OR %iam_roles !empty OR %iam_users !empty OR %iam_policies !empty OR %iam_managedpolicies !empty{
	when %iam_groups !empty {
		%iam_groups {
			Properties {
				when Policies exists {
					Policies.* {
						PolicyDocument {
							Statement.*[
								Effect == "Allow"
								some Action[*] IN ["iam:CreateAccessKey", "iam:CreateLoginProfile", "iam:UpdateLoginProfile", "iam:AttachUserPolicy", "iam:AttachGroupPolicy", "iam:AttachRolePolicy", "iam:PutUserPolicy", "iam:PutGroupPolicy", "iam:PutRolePolicy", "iam:CreatePolicy", "iam:AddUserToGroup", "iam:UpdateAssumeRolePolicy", "iam:CreatePolicyVersion", "iam:SetDefaultPolicyVersion", "iam:AddUserToGroup"]
								some Resource[*] == "*"
							] empty <<IAM group were found with a policy that allows access to sensitive IAM actions>>
						}
					}
				}
			}
		}
	}
	
	when %iam_roles !empty {
		%iam_roles {
			Properties {
				when Policies exists {
					Policies.* {
						PolicyDocument {
							Statement.*[
								Effect == "Allow"
								some Action[*] IN ["iam:CreateAccessKey", "iam:CreateLoginProfile", "iam:UpdateLoginProfile", "iam:AttachUserPolicy", "iam:AttachGroupPolicy", "iam:AttachRolePolicy", "iam:PutUserPolicy", "iam:PutGroupPolicy", "iam:PutRolePolicy", "iam:CreatePolicy", "iam:AddUserToGroup", "iam:UpdateAssumeRolePolicy", "iam:CreatePolicyVersion", "iam:SetDefaultPolicyVersion", "iam:AddUserToGroup"]
								some Resource[*] == "*"
							] empty <<IAM role found with a policy that allows access to sensitive IAM actions>>
						}
					}
				}
			}
		}
	}

	when %iam_users !empty {
		%iam_users {
			Properties {
				when Policies exists {
					Policies.* {
						PolicyDocument {
							Statement.*[
								Effect == "Allow"
								some Action[*] IN ["iam:CreateAccessKey", "iam:CreateLoginProfile", "iam:UpdateLoginProfile", "iam:AttachUserPolicy", "iam:AttachGroupPolicy", "iam:AttachRolePolicy", "iam:PutUserPolicy", "iam:PutGroupPolicy", "iam:PutRolePolicy", "iam:CreatePolicy", "iam:AddUserToGroup", "iam:UpdateAssumeRolePolicy", "iam:CreatePolicyVersion", "iam:SetDefaultPolicyVersion", "iam:AddUserToGroup"]
								some Resource[*] == "*"
							] empty <<IAM user found with a policy that allows access to sensitive IAM actions>>
						}
					}
				}
			}
		}
	}

	when %iam_policies !empty {
		%iam_policies {
			Properties {
				PolicyDocument {
					Statement.*[
						Effect == "Allow"
						some Action[*] IN ["iam:CreateAccessKey", "iam:CreateLoginProfile", "iam:UpdateLoginProfile", "iam:AttachUserPolicy", "iam:AttachGroupPolicy", "iam:AttachRolePolicy", "iam:PutUserPolicy", "iam:PutGroupPolicy", "iam:PutRolePolicy", "iam:CreatePolicy", "iam:AddUserToGroup", "iam:UpdateAssumeRolePolicy", "iam:CreatePolicyVersion", "iam:SetDefaultPolicyVersion", "iam:AddUserToGroup"]
						some Resource[*] == "*"
					] empty <<IAM policy found that allows access to sensitive IAM actions>>
				}
			}
		}
	}

	when %iam_managedpolicies !empty {
		%iam_managedpolicies {
			Properties {
				PolicyDocument {
					Statement.*[
						Effect == "Allow"
						some Action[*] IN ["iam:CreateAccessKey", "iam:CreateLoginProfile", "iam:UpdateLoginProfile", "iam:AttachUserPolicy", "iam:AttachGroupPolicy", "iam:AttachRolePolicy", "iam:PutUserPolicy", "iam:PutGroupPolicy", "iam:PutRolePolicy", "iam:CreatePolicy", "iam:AddUserToGroup", "iam:UpdateAssumeRolePolicy", "iam:CreatePolicyVersion", "iam:SetDefaultPolicyVersion", "iam:AddUserToGroup"]
						some Resource[*] == "*"
					] empty <<IAM managed policy found that allows access to sensitive IAM actions>>
				}
			}
		}
	}
}

rule iam_policy_s3_readallaccess when %iam_groups !empty OR %iam_roles !empty OR %iam_users !empty OR %iam_policies !empty OR %iam_managedpolicies !empty{
	when %iam_groups !empty {
		%iam_groups {
			Properties {
				when Policies exists {
					Policies.* {
						PolicyDocument {
							Statement.*[
								Effect == "Allow"
								some Action[*] == "s3:GetObject"
								some Resource[*] == "*"
							] empty <<IAM group were found with a policy that allows unrestricted S3 GetObject access to all buckets>>
						}
					}
				}
			}
		}
	}
	
	when %iam_roles !empty {
		%iam_roles {
			Properties {
				when Policies exists {
					Policies.* {
						PolicyDocument {
							Statement.*[
								Effect == "Allow"
								some Action[*] == "s3:GetObject"
								some Resource[*] == "*"
							] empty <<IAM role found with a policy that allows unrestricted S3 GetObject access to all buckets>>
						}
					}
				}
			}
		}
	}

	when %iam_users !empty {
		%iam_users {
			Properties {
				when Policies exists {
					Policies.* {
						PolicyDocument {
							Statement.*[
								Effect == "Allow"
								some Action[*] == "s3:GetObject"
								some Resource[*] == "*"
							] empty <<IAM user found with a policy that allows unrestricted S3 GetObject access to all buckets>>
						}
					}
				}
			}
		}
	}

	when %iam_policies !empty {
		%iam_policies {
			Properties {
				PolicyDocument {
					Statement.*[
						Effect == "Allow"
						some Action[*] == "s3:GetObject"
						some Resource[*] == "*"
					] empty <<IAM policy found that allows unrestricted S3 GetObject access to all buckets>>
				}
			}
		}
	}

	when %iam_managedpolicies !empty {
		%iam_managedpolicies {
			Properties {
				PolicyDocument {
					Statement.*[
						Effect == "Allow"
						some Action[*] == "s3:GetObject"
						some Resource[*] == "*"
					] empty <<IAM managed policy found that allows unrestricted S3 GetObject access to all buckets>>
				}
			}
		}
	}
}

rule iam_policy_lambda_invoke_all when %iam_groups !empty OR %iam_roles !empty OR %iam_users !empty OR %iam_policies !empty OR %iam_managedpolicies !empty{
	when %iam_groups !empty {
		%iam_groups {
			Properties {
				when Policies exists {
					Policies.* {
						PolicyDocument {
							Statement.*[
								Effect == "Allow"
								some Action[*] == "lambda:InvokeFunction"
								some Resource[*] == "*"
							] empty <<IAM group were found with a policy that allows unrestricted Lambda Invoke Function to all functions>>
						}
					}
				}
			}
		}
	}
	
	when %iam_roles !empty {
		%iam_roles {
			Properties {
				when Policies exists {
					Policies.* {
						PolicyDocument {
							Statement.*[
								Effect == "Allow"
								some Action[*] == "lambda:InvokeFunction"
								some Resource[*] == "*"
							] empty <<IAM role found with a policy that allows unrestricted Lambda Invoke Function to all functions>>
						}
					}
				}
			}
		}
	}

	when %iam_users !empty {
		%iam_users {
			Properties {
				when Policies exists {
					Policies.* {
						PolicyDocument {
							Statement.*[
								Effect == "Allow"
								some Action[*] == "lambda:InvokeFunction"
								some Resource[*] == "*"
							] empty <<IAM user found with a policy that allows unrestricted Lambda Invoke Function to all functions>>
						}
					}
				}
			}
		}
	}

	when %iam_policies !empty {
		%iam_policies {
			Properties {
				PolicyDocument {
					Statement.*[
						Effect == "Allow"
						some Action[*] == "lambda:InvokeFunction"
						some Resource[*] == "*"
					] empty <<IAM policy found that allows unrestricted Lambda Invoke Function to all functions>>
				}
			}
		}
	}

	when %iam_managedpolicies !empty {
		%iam_managedpolicies {
			Properties {
				PolicyDocument {
					Statement.*[
						Effect == "Allow"
						some Action[*] == "lambda:InvokeFunction"
						some Resource[*] == "*"
					] empty <<IAM managed policy found that allows unrestricted Lambda Invoke Function to all functions>>
				}
			}
		}
	}
}

rule iam_policy_secretsmanager_allaccess when %iam_groups !empty OR %iam_roles !empty OR %iam_users !empty OR %iam_policies !empty OR %iam_managedpolicies !empty{
	when %iam_groups !empty {
		%iam_groups {
			Properties {
				when Policies exists {
					Policies.* {
						PolicyDocument {
							Statement.*[
								Effect == "Allow"
								some Action[*] == "secretsmanager:GetSecretValue"
								some Resource[*] == "*"
							] empty <<IAM group were found with a policy that allows unrestricted secretsmanager:GetSecretValue>>
						}
					}
				}
			}
		}
	}
	
	when %iam_roles !empty {
		%iam_roles {
			Properties {
				when Policies exists {
					Policies.* {
						PolicyDocument {
							Statement.*[
								Effect == "Allow"
								some Action[*] == "secretsmanager:GetSecretValue"
								some Resource[*] == "*"
							] empty <<IAM role found with a policy that allows unrestricted secretsmanager:GetSecretValue>>
						}
					}
				}
			}
		}
	}

	when %iam_users !empty {
		%iam_users {
			Properties {
				when Policies exists {
					Policies.* {
						PolicyDocument {
							Statement.*[
								Effect == "Allow"
								some Action[*] == "secretsmanager:GetSecretValue"
								some Resource[*] == "*"
							] empty <<IAM user found with a policy that allows unrestricted secretsmanager:GetSecretValue>>
						}
					}
				}
			}
		}
	}

	when %iam_policies !empty {
		%iam_policies {
			Properties {
				PolicyDocument {
					Statement.*[
						Effect == "Allow"
						some Action[*] == "secretsmanager:GetSecretValue"
						some Resource[*] == "*"
					] empty <<IAM policy found that allows unrestricted secretsmanager:GetSecretValue>>
				}
			}
		}
	}

	when %iam_managedpolicies !empty {
		%iam_managedpolicies {
			Properties {
				PolicyDocument {
					Statement.*[
						Effect == "Allow"
						some Action[*] == "secretsmanager:GetSecretValue"
						some Resource[*] == "*"
					] empty <<IAM managed policy found that allows unrestricted secretsmanager:GetSecretValue>>
				}
			}
		}
	}
}

rule iam_role_assume_public when %iam_roles !empty {
	%iam_roles {
		Properties {
			AssumeRolePolicyDocument {
				Statement.*[
					Effect == "Allow"
					Principal == "*" OR some Principal.AWS[*] == "*"
				] empty <<IAM Role can be assumed publicly>>
			}
		}
	}
}

rule iam_user_attached_policies when %iam_groups !empty OR %iam_roles !empty OR %iam_users !empty OR %iam_policies !empty OR %iam_managedpolicies !empty{
	when %iam_users !empty {
		%iam_users {
			Properties {
				ManagedPolicyArns !exists <<ManagedPolicyArns found with IAM user>>
				Policies !exists <<Policies found with IAM user>>
			}
		}
	}

	when %iam_policies !empty {
		%iam_policies {
			Properties {
				Users !exists <<IAM user found with policy>>
			}
		}
	}

	when %iam_managedpolicies !empty {
		%iam_managedpolicies {
			Properties {
				Users !exists <<IAM user found with managed policy>>
			}
		}
	}
}

rule iam_group_user_role_no_inline_policies when %iam_groups !empty OR %iam_roles !empty OR %iam_users !empty OR %iam_policies !empty OR %iam_managedpolicies !empty{
	when %iam_groups !empty {
		%iam_groups {
			Properties {
				Policies !exists <<Inline policies found with IAM Group>>
			}
		}
	}
	
	when %iam_roles !empty {
		%iam_roles {
			Properties {
				Policies !exists <<Inline policies found with IAM Role>>
			}
		}
	}

	when %iam_users !empty {
		%iam_users {
			Properties {
				Policies !exists <<Inline policies found with IAM user>>
			}
		}
	}

	when %iam_policies !empty {
		%iam_policies {
			Properties {
				Groups !exists <<IAM Groups found with inline policy>>
				Roles !exists <<IAM Roles found with inline policy>>
				Users !exists <<IAM Users found with inline policy>>
			}
		}
	}
}



let ebs_volumes = Resources.*[
	Type == "AWS::EC2::Volume"
]

let ec2_instances = Resources.*[
	Type == "AWS::EC2::Instance"
]

rule ec2_ebs_encryption when %ebs_volumes !empty OR %ec2_instances !empty {
	when %ebs_volumes !empty {
		%ebs_volumes {
			Properties {
				Encrypted exists <<Encryption not configured. (Defaults to region default settings.)>>
				when Encrypted exists {
					Encrypted == true <<Encryption is disabled.>>
				}
			}
		}
	}

	when %ec2_instances !empty {
		%ec2_instances {
			Properties {
				when BlockDeviceMappings exists {
					BlockDeviceMappings.* {
						when Ebs exists {
							Ebs {
								Encrypted exists <<Encryption not configured. (Defaults to region default settings.)>>
								when Encrypted exists {
									Encrypted == true <<Encryption is disabled.>>
								}
							}
						}
					}
				}
			}
		}
	}
}

rule ec2_termination_protection when %ec2_instances !empty {
	%ec2_instances {
		Properties {
			DisableApiTermination !exists OR
			DisableApiTermination exists
			when DisableApiTermination exists {
				DisableApiTermination == true <<Termination protection is disabled.>>
			}
		}
	}
}

rule ec2_instance_ebs_optimized when %ec2_instances !empty {
	%ec2_instances {
		Properties {
			EbsOptimized exists <<EbsOptimized is not configured. (i.e. disabled)>>
			when EbsOptimized exists {
				EbsOptimized == true <<EbsOptimized is disabled.>>
			}
		}
	}
}

rule ec2_ebs_attached_volume_delete_on_termination_enabled when %ec2_instances !empty {
	%ec2_instances {
		Properties {
			when BlockDeviceMappings exists {
				BlockDeviceMappings.* {
					when Ebs exists {
						Ebs {
							DeleteOnTermination !exists OR
							DeleteOnTermination exists
							when DeleteOnTermination exists {
								DeleteOnTermination == true <<DeleteOnTermination is disabled.>>
							}
						}
					}
				}
			}
		}
	}
}

rule ec2_instance_detailed_monitoring_enabled when %ec2_instances !empty {
	%ec2_instances {
		Properties {
			Monitoring exists <<Monitoring is not configured. (i.e. disabled)>>
			when Monitoring exists {
				Monitoring == true <<Enhanced monitoring is disabled.>>
			}
		}
	}
}

rule ec2_iam_associated when %ec2_instances !empty {
	%ec2_instances {
		Properties {
			IamInstanceProfile exists <<IamInstanceProfile is not configured. (i.e. disabled)>>
		}
	}
}



let s3_buckets = Resources.*[
	Type == "AWS::S3::Bucket"
]

rule s3_access_logging when %s3_buckets !empty {
	%s3_buckets {
		Properties {
			LoggingConfiguration exists <<Logging is not configured.>>
		}
	}
}

rule s3_bucket_versioning when %s3_buckets !empty {
	%s3_buckets {
		Properties {
			VersioningConfiguration exists <<Bucket versioning is not configured (i.e. disabled).>>
			when VersioningConfiguration exists {
				VersioningConfiguration {
					Status exists <<Bucket versioning status is not configured (i.e. disabled).>>
					when Status exists {
						Status == "Enabled" <<Bucket versioning is not enabled.>>
					}
				}
			}
		}
	}
}

rule s3_bucket_object_lock_enabled when %s3_buckets !empty {
	%s3_buckets {
		Properties {
			ObjectLockEnabled exists <<ObjectLockEnabled is not set (i.e. disabled).>>
			when ObjectLockEnabled exists {
				ObjectLockEnabled == true <<Object Lock is disabled.>>
			}
		}
	}
}

rule s3_bucket_encryption when %s3_buckets !empty {
	%s3_buckets {
		Properties {
			BucketEncryption exists <<BucketEncryption is not configured. (i.e. disabled)>>
			when BucketEncryption exists {
				BucketEncryption {
					some ServerSideEncryptionConfiguration.* {
						ServerSideEncryptionByDefault exists <<ServerSideEncryptionByDefault is not configured. (i.e. disabled)>>
					}
				}
			}
		}
	}
}

rule s3_bucket_kms_encryption when %s3_buckets !empty {
	%s3_buckets {
		Properties {
			BucketEncryption exists <<BucketEncryption is not configured. (i.e. disabled)>>
			when BucketEncryption exists {
				BucketEncryption {
					some ServerSideEncryptionConfiguration.* {
						ServerSideEncryptionByDefault exists <<ServerSideEncryptionByDefault is not configured. (i.e. disabled)>>
						when ServerSideEncryptionByDefault exists {
							ServerSideEncryptionByDefault {
								SSEAlgorithm == "aws:kms" <<KMS encryptionm not used.>>
							}
						}
					}
				}
			}
		}
	}
}

rule s3_bucket_key_enabled when %s3_buckets !empty {
	%s3_buckets {
		Properties {
			when BucketEncryption exists {
				BucketEncryption {
					some ServerSideEncryptionConfiguration.* {
						when ServerSideEncryptionByDefault exists {
							when ServerSideEncryptionByDefault.SSEAlgorithm == "aws:kms" {
								BucketKeyEnabled == true <<Bucket Key is disabled.>>
							}
						}
					}
				}
			}
		}
	}
}



let sg_resources = Resources.*[
	Type == "AWS::EC2::SecurityGroup"
]

rule prevent_inbound_access_to_any_ip when %sg_resources !empty {
	%sg_resources {
		Properties {
			SecurityGroupIngress !exists or
			SecurityGroupIngress exists

			when SecurityGroupIngress exists {
				SecurityGroupIngress.* {
					when CidrIp exists {
						CidrIp		!= '0.0.0.0/0' <<IPv4 address cannot be 0.0.0.0/0>>
					}
					when CidrIpv6 exists {
						CidrIpv6	!= '::/0' <<IPv6 address cannot be ::/0>>
					}
				}
			}
		}
	}
}

rule prevent_outbound_access_to_any_ip when %sg_resources !empty {
	%sg_resources {
		Properties {
			SecurityGroupEgress exists <<All outbound traffic is allowed.>>

			when SecurityGroupEgress exists {
				SecurityGroupEgress.* {
					when CidrIp exists {
						CidrIp		!= '0.0.0.0/0' <<IPv4 address cannot be 0.0.0.0/0>>
					}
					when CidrIpv6 exists {
						CidrIpv6	!= '::/0' <<IPv6 address cannot be ::/0>>
					}
				}
			}
		}
	}
}

rule prevent_inbound_access_to_any_ports when %sg_resources !empty {
	%sg_resources {
		Properties {
			SecurityGroupIngress !exists or
			SecurityGroupIngress exists

			when SecurityGroupIngress exists {
				SecurityGroupIngress.* {
					IpProtocol != -1 <<All inbound traffic is allowed.>>

					when IpProtocol in ['tcp', 'udp'] {
						when FromPort == 0 {
							ToPort		!= 65535 <<All ingress ports should not be open>>
						}
					}
				}
			}
		}
	}
}

rule prevent_outbound_access_to_any_ports when %sg_resources !empty {
	%sg_resources {
		Properties {
			SecurityGroupEgress exists <<All outbound traffic is allowed.>>

			when SecurityGroupEgress exists {
				SecurityGroupEgress.* {
					IpProtocol != -1 <<All outbound traffic is allowed.>>

					when IpProtocol in ['tcp', 'udp'] {
						when FromPort == 0 {
							ToPort		!= 65535 <<All egress ports are open.>>
						}
					}
				}
			}
		}
	}
}

rule sg_ssh_all when %sg_resources !empty {
	%sg_resources {
		Properties {
			SecurityGroupIngress !exists OR
			SecurityGroupIngress exists

			when SecurityGroupIngress exists {
				SecurityGroupIngress.* {
					when IpProtocol == -1 {
						when CidrIp exists {
							CidrIp		!= '0.0.0.0/0' <<All traffic open to IPv4 address 0.0.0.0/0>>
						}
						when CidrIpv6 exists {
							CidrIpv6	!= '::/0' <<All traffic open to IPv6 address ::/0>>
						}
					}

					when IpProtocol == 'tcp' {
						when FromPort <= 22 
						ToPort >= 22 {
							when CidrIp exists {
								CidrIp		!= '0.0.0.0/0' <<SSH open to IPv4 address 0.0.0.0/0>>
							}
							when CidrIpv6 exists {
								CidrIpv6	!= '::/0' <<SSH open to IPv6 address ::/0>>
							}
						}
					}
				}
			}
		}
	}
}

rule sg_rdp_all when %sg_resources !empty {
	%sg_resources {
		Properties {
			SecurityGroupIngress !exists OR
			SecurityGroupIngress exists

			when SecurityGroupIngress exists {
				SecurityGroupIngress.* {
					when IpProtocol == -1 {
						when CidrIp exists {
							CidrIp		!= '0.0.0.0/0' <<All traffic open to IPv4 address 0.0.0.0/0>>
						}
						when CidrIpv6 exists {
							CidrIpv6	!= '::/0' <<All traffic open to IPv6 address ::/0>>
						}
					}

					when IpProtocol == 'tcp' {
						when FromPort <= 3389 
						ToPort >= 3389 {
							when CidrIp exists {
								CidrIp		!= '0.0.0.0/0' <<RDP open to IPv4 address 0.0.0.0/0>>
							}
							when CidrIpv6 exists {
								CidrIpv6	!= '::/0' <<RDP open to IPv6 address ::/0>>
							}
						}
					}
				}
			}
		}
	}
}

rule sg_oracle_all when %sg_resources !empty {
	%sg_resources {
		Properties {
			SecurityGroupIngress !exists OR
			SecurityGroupIngress exists

			when SecurityGroupIngress exists {
				SecurityGroupIngress.* {
					when IpProtocol == -1 {
						when CidrIp exists {
							CidrIp		!= '0.0.0.0/0' <<All traffic open to IPv4 address 0.0.0.0/0>>
						}
						when CidrIpv6 exists {
							CidrIpv6	!= '::/0' <<All traffic open to IPv6 address ::/0>>
						}
					}

					when IpProtocol == 'tcp' {
						when FromPort <= 1521
						ToPort >= 1521 {
							when CidrIp exists {
								CidrIp		!= '0.0.0.0/0' <<Oracle open to IPv4 address 0.0.0.0/0>>
							}
							when CidrIpv6 exists {
								CidrIpv6	!= '::/0' <<Oracle open to IPv6 address ::/0>>
							}
						}

						when FromPort <= 2483
						ToPort >= 2483 {
							when CidrIp exists {
								CidrIp		!= '0.0.0.0/0' <<Oracle open to IPv4 address 0.0.0.0/0>>
							}
							when CidrIpv6 exists {
								CidrIpv6	!= '::/0' <<Oracle open to IPv6 address ::/0>>
							}
						}
					}
				}
			}
		}
	}
}

rule sg_mysql_all when %sg_resources !empty {
	%sg_resources {
		Properties {
			SecurityGroupIngress !exists OR
			SecurityGroupIngress exists

			when SecurityGroupIngress exists {
				SecurityGroupIngress.* {
					when IpProtocol == -1 {
						when CidrIp exists {
							CidrIp		!= '0.0.0.0/0' <<All traffic open to IPv4 address 0.0.0.0/0>>
						}
						when CidrIpv6 exists {
							CidrIpv6	!= '::/0' <<All traffic open to IPv6 address ::/0>>
						}
					}

					when IpProtocol == 'tcp' {
						when FromPort <= 3306 
						ToPort >= 3306 {
							when CidrIp exists {
								CidrIp		!= '0.0.0.0/0' <<MySQL open to IPv4 address 0.0.0.0/0>>
							}
							when CidrIpv6 exists {
								CidrIpv6	!= '::/0' <<MySQL open to IPv6 address ::/0>>
							}
						}
					}
				}
			}
		}
	}
}

rule sg_postgres_all when %sg_resources !empty {
	%sg_resources {
		Properties {
			SecurityGroupIngress !exists OR
			SecurityGroupIngress exists

			when SecurityGroupIngress exists {
				SecurityGroupIngress.* {
					when IpProtocol == -1 {
						when CidrIp exists {
							CidrIp		!= '0.0.0.0/0' <<All traffic open to IPv4 address 0.0.0.0/0>>
						}
						when CidrIpv6 exists {
							CidrIpv6	!= '::/0' <<All traffic open to IPv6 address ::/0>>
						}
					}

					when IpProtocol == 'tcp' {
						when FromPort <= 5432 
						ToPort >= 5432 {
							when CidrIp exists {
								CidrIp		!= '0.0.0.0/0' <<PostgreSQL open to IPv4 address 0.0.0.0/0>>
							}
							when CidrIpv6 exists {
								CidrIpv6	!= '::/0' <<PostgreSQL open to IPv6 address ::/0>>
							}
						}
					}
				}
			}
		}
	}
}

rule sg_redis_all when %sg_resources !empty {
	%sg_resources {
		Properties {
			SecurityGroupIngress !exists OR
			SecurityGroupIngress exists

			when SecurityGroupIngress exists {
				SecurityGroupIngress.* {
					when IpProtocol == -1 {
						when CidrIp exists {
							CidrIp		!= '0.0.0.0/0' <<All traffic open to IPv4 address 0.0.0.0/0>>
						}
						when CidrIpv6 exists {
							CidrIpv6	!= '::/0' <<All traffic open to IPv6 address ::/0>>
						}
					}

					when IpProtocol == 'tcp' {
						when FromPort <= 6379 
						ToPort >= 6379 {
							when CidrIp exists {
								CidrIp		!= '0.0.0.0/0' <<Redis open to IPv4 address 0.0.0.0/0>>
							}
							when CidrIpv6 exists {
								CidrIpv6	!= '::/0' <<Redis open to IPv6 address ::/0>>
							}
						}
					}
				}
			}
		}
	}
}

rule sg_mongodb_all when %sg_resources !empty {
	%sg_resources {
		Properties {
			SecurityGroupIngress !exists OR
			SecurityGroupIngress exists

			when SecurityGroupIngress exists {
				SecurityGroupIngress.* {
					when IpProtocol == -1 {
						when CidrIp exists {
							CidrIp		!= '0.0.0.0/0' <<All traffic open to IPv4 address 0.0.0.0/0>>
						}
						when CidrIpv6 exists {
							CidrIpv6	!= '::/0' <<All traffic open to IPv6 address ::/0>>
						}
					}

					when IpProtocol == 'tcp' {
						when FromPort <= 27017
						ToPort >= 27017 {
							when CidrIp exists {
								CidrIp		!= '0.0.0.0/0' <<MongoDB open to IPv4 address 0.0.0.0/0>>
							}
							when CidrIpv6 exists {
								CidrIpv6	!= '::/0' <<MongoDB open to IPv6 address ::/0>>
							}
						}

						when FromPort <= 27018
						ToPort >= 27018 {
							when CidrIp exists {
								CidrIp		!= '0.0.0.0/0' <<MongoDB open to IPv4 address 0.0.0.0/0>>
							}
							when CidrIpv6 exists {
								CidrIpv6	!= '::/0' <<MongoDB open to IPv6 address ::/0>>
							}
						}
					}
				}
			}
		}
	}
}

rule sg_cassandra_all when %sg_resources !empty {
	%sg_resources {
		Properties {
			SecurityGroupIngress !exists OR
			SecurityGroupIngress exists

			when SecurityGroupIngress exists {
				SecurityGroupIngress.* {
					when IpProtocol == -1 {
						when CidrIp exists {
							CidrIp		!= '0.0.0.0/0' <<All traffic open to IPv4 address 0.0.0.0/0>>
						}
						when CidrIpv6 exists {
							CidrIpv6	!= '::/0' <<All traffic open to IPv6 address ::/0>>
						}
					}

					when IpProtocol == 'tcp' {
						when FromPort <= 7199
						ToPort >= 7199 {
							when CidrIp exists {
								CidrIp		!= '0.0.0.0/0' <<Cassandra open to IPv4 address 0.0.0.0/0>>
							}
							when CidrIpv6 exists {
								CidrIpv6	!= '::/0' <<Cassandra open to IPv6 address ::/0>>
							}
						}

						when FromPort <= 9160
						ToPort >= 9160 {
							when CidrIp exists {
								CidrIp		!= '0.0.0.0/0' <<Cassandra open to IPv4 address 0.0.0.0/0>>
							}
							when CidrIpv6 exists {
								CidrIpv6	!= '::/0' <<Cassandra open to IPv6 address ::/0>>
							}
						}

						when FromPort <= 8888
						ToPort >= 8888 {
							when CidrIp exists {
								CidrIp		!= '0.0.0.0/0' <<Cassandra open to IPv4 address 0.0.0.0/0>>
							}
							when CidrIpv6 exists {
								CidrIpv6	!= '::/0' <<Cassandra open to IPv6 address ::/0>>
							}
						}
					}
				}
			}
		}
	}
}

rule sg_memcached_all when %sg_resources !empty {
	%sg_resources {
		Properties {
			SecurityGroupIngress !exists OR
			SecurityGroupIngress exists

			when SecurityGroupIngress exists {
				SecurityGroupIngress.* {
					when IpProtocol == -1 {
						when CidrIp exists {
							CidrIp		!= '0.0.0.0/0' <<All traffic open to IPv4 address 0.0.0.0/0>>
						}
						when CidrIpv6 exists {
							CidrIpv6	!= '::/0' <<All traffic open to IPv6 address ::/0>>
						}
					}

					when IpProtocol == 'tcp' {
						when FromPort <= 11211 
						ToPort >= 11211 {
							when CidrIp exists {
								CidrIp		!= '0.0.0.0/0' <<Memcached open to IPv4 address 0.0.0.0/0>>
							}
							when CidrIpv6 exists {
								CidrIpv6	!= '::/0' <<Memcached open to IPv6 address ::/0>>
							}
						}
					}
				}
			}
		}
	}
}

rule sg_insecure_ports when %sg_resources !empty {
	%sg_resources {
		Properties {
			SecurityGroupIngress !exists OR
			SecurityGroupIngress exists

			when SecurityGroupIngress exists {
				SecurityGroupIngress.* {
					IpProtocol != -1 <<All inbound ports are open.>>
					when IpProtocol != -1 {
						FromPort > 21 OR
						ToPort < 21
						FromPort > 23 OR
						ToPort < 23
						FromPort > 80 OR
						ToPort < 80
						FromPort > 389 OR
						ToPort < 389
						FromPort > 4333 OR
						ToPort < 4333
					}
				}
			}
		}
	}
}




let vpc_subnets = Resources.*[
	Type == "AWS::EC2::Subnet"
]

rule vpc_auto_assign_ip_disabled when %vpc_subnets !empty {
	%vpc_subnets {
		Properties {
			MapPublicIpOnLaunch not exists OR
			MapPublicIpOnLaunch exists
			when MapPublicIpOnLaunch exists {
				MapPublicIpOnLaunch == false <<MapPublicIpOnLaunch is enabled.>>
			}
		}
	}
}



let ddb_tables = Resources.*[
	Type == "AWS::DynamoDB::Table"
]

rule dynamodb_server_side_encryption when %ddb_tables !empty {
	%ddb_tables {
		Properties {
			SSESpecification exists <<DynamoDB Table does not have SSESpecification explicitly configured (server-side encryption is set to AWS owned key).>>
			when SSESpecification exists {
				SSESpecification {
					SSEEnabled exists <<SSEEnabled is not set (server-side encryption is set to AWS owned key)>>
					when SSEEnabled exists {
						SSEEnabled == true <<DynamoDB Table has SSE disabled (server-side encryption is set to AWS owned key).>>
						when SSEEnabled == true {
							SSEType !exists OR
							when SSEType exists {
								SSEType == 'KMS' <<DynamoDB Table should have SSE with KMS.>>
							}
						}
					}
				}
			}
		}
	}
}

rule dynamodb_PITR_enabled when %ddb_tables !empty {
	%ddb_tables {
		Properties {
			PointInTimeRecoverySpecification exists <<DynamoDB Table does not have PointInTimeRecoverySpecification configured (i.e. disabled).>>
			when PointInTimeRecoverySpecification exists {
				PointInTimeRecoverySpecification {
					PointInTimeRecoveryEnabled exists <<PointInTimeRecoveryEnabled is not set (i.e. disabled).>>
					when PointInTimeRecoveryEnabled exists {
						PointInTimeRecoveryEnabled == true <<DynamoDB Table has Point In Time Recovery disabled.>>
					}
				}
			}
		}
	}
}

let dax_clusters = Resources.*[
	Type == "AWS::DAX::Cluster"
]

rule dax_encryption_at_rest when %dax_clusters !empty {
	%dax_clusters {
		Properties {
			SSESpecification exists <<DAX cluster does not have SSESpecification configured (i.e. disabled).>>
			when SSESpecification exists {
				SSESpecification {
					SSEEnabled exists <<SSEEnabled is not set (i.e. disabled).>>
					when SSEEnabled exists {
						SSEEnabled == true <<DAX cluster has SSE disabled.>>
					}
				}
			}
		}
	}
}

rule dax_encryption_in_transit when %dax_clusters !empty {
	%dax_clusters {
		Properties {
			ClusterEndpointEncryptionType exists <<ClusterEndpointEncryptionType defaults to NONE (i.e. disabled).>>
			when ClusterEndpointEncryptionType exists {
				ClusterEndpointEncryptionType != "NONE" <<ClusterEndpointEncryptionType is disabled.>>
			}
		}
	}
}



let kms_keys = Resources.*[
	Type == "AWS::KMS::Key"
]

rule kms_rotation when %kms_keys !empty {
	%kms_keys {
		Properties {
			when KeySpec !exists {
				EnableKeyRotation exists <<EnableKeyRotation is not configured (i.e. disabled).>>
				when EnableKeyRotation exists {
					EnableKeyRotation == true <<Key Rotation is disabled.>>
				}
			}
            
			when KeySpec exists {
				when KeySpec == "SYMMETRIC_DEFAULT" {
					EnableKeyRotation exists <<EnableKeyRotation is not configured (i.e. disabled).>>
					when EnableKeyRotation exists {
						EnableKeyRotation == true <<Key Rotation is disabled.>>
					}
				}
			}
		}
	}
}

rule kms_public when %kms_keys !empty {
	%kms_keys {
		Properties {
			KeyPolicy {
				Statement.* {
					Effect == "Deny" OR
					when Effect == "Allow" {
						Principal != "*" <<Key policy allows public access ("AWS":"*")>>
					}
				}
			}
		}
	}
}



let elb_lbs = Resources.*[
	Type == "AWS::ElasticLoadBalancing::LoadBalancer"
]

let elbv2_lbs = Resources.*[
	Type == "AWS::ElasticLoadBalancingV2::LoadBalancer"
]

rule elb_access_logging when %elb_lbs !empty OR %elbv2_lbs !empty {
	when %elb_lbs !empty {
		%elb_lbs {
			Properties {
				AccessLoggingPolicy exists <<AccessLoggingPolicy not configured. (i.e. disabled)>>
				when AccessLoggingPolicy exists {
					AccessLoggingPolicy {
						Enabled == true <<Access Logging is disabled.>>
					}
				}
			}
		}
	}

	when %elbv2_lbs !empty {
		%elbv2_lbs {
			Properties {
				when Type !exists OR Type != "gateway" {
					LoadBalancerAttributes exists <<LoadBalancerAttributes not configured. (i.e. disabled)>>
					when LoadBalancerAttributes exists {
						some LoadBalancerAttributes[*] {
							Key == "access_logs.s3.enabled"
							Value == "true"
						}
					}
				}
			}
		}
	}
}

rule elb_public_classic_load_balancers when %elb_lbs !empty {
	%elb_lbs {
		Properties {
			Scheme !exists OR
			Scheme exists
			when Scheme exists {
				Scheme != "internet-facing" <<Load Balancer is internet facing.>>
			}
		}
	}
}

rule alb_deletion_protection when %elbv2_lbs !empty {
	%elbv2_lbs {
		Properties {
			LoadBalancerAttributes exists <<LoadBalancerAttributes not configured. (i.e. disabled)>>
			when LoadBalancerAttributes exists {
				some LoadBalancerAttributes[*] {
					Key == "deletion_protection.enabled"
					Value == "true"
				}
			}
		}
	}
}

rule elb_classic_lb_use_ssl_certificate when %elb_lbs !empty {
	%elb_lbs {
		Properties {
			Listeners[*] {
				Protocol in ["HTTPS", "SSL"] <<Load Balancer does not have secure listeners.>>
			}
		}
	}
}

rule alb_drop_http_headers when %elbv2_lbs !empty {
	%elbv2_lbs {
		Properties {
			when Type !exists OR Type == "application" {
				LoadBalancerAttributes exists <<LoadBalancerAttributes not configured. (i.e. disabled)>>
				when LoadBalancerAttributes exists {
					some LoadBalancerAttributes[*] {
						Key == "routing.http.drop_invalid_header_fields.enabled"
						Value == "true"
					}
				}
			}
		}
	}
}

rule elb_cross_zone_load_balancing when %elb_lbs !empty OR %elbv2_lbs !empty {
	when %elb_lbs !empty {
		%elb_lbs {
			Properties {
				CrossZone exists <<CrossZone not configured. (i.e. disabled)>>
				when CrossZone exists {
					CrossZone == true <<Cross zone is disabled.>>
				}
			}
		}
	}

	when %elbv2_lbs !empty {
		%elbv2_lbs {
			Properties {
				when Type exists
				Type != "application" {
					LoadBalancerAttributes exists <<LoadBalancerAttributes not configured. (i.e. disabled)>>
					when LoadBalancerAttributes exists {
						some LoadBalancerAttributes[*] {
							Key == "load_balancing.cross_zone.enabled"
							Value == "true"
						}
					}
				}
			}
		}
	}
}

rule elb_classic_connection_draining when %elb_lbs !empty {
	%elb_lbs {
		Properties {
			ConnectionDrainingPolicy exists <<ConnectionDrainingPolicy is not configured.(i.e. disabled)>>
			when ConnectionDrainingPolicy exists {
				ConnectionDrainingPolicy {
					Enabled == true <<Connection Draining is disabled.>>
				}
			}
		}
	}
}



let secretsmanager_secrets = Resources.*[
	Type == "AWS::SecretsManager::Secret"
]

rule secretsmanager_cross_region_replication when %secretsmanager_secrets !empty {
	%secretsmanager_secrets {
		Properties {
			ReplicaRegions exists <<Cross region replication is disabled.>>
		}
	}
}


Actions



Customize Template

Configuration Presets

Resource Settings

EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT
EDIT