diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index f7bf412..8841d66 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -14,4 +14,10 @@ RUN POETRY_VERSION=1.5.1 POETRY_HOME=/home/vscode/.local/ python poetryInstallSc # AWS Cloudformation RUN apt-get install -y python3-pip="22.0.2+dfsg-1ubuntu0.3" -RUN pip install cfn-lint=='0.79.5' \ No newline at end of file +RUN pip install cfn-lint=='0.79.5' + +# This is partially duplicated in ci.yaml, with the copy target being the only difference +RUN mkdir ./cfn-guard-temp/ +RUN wget https://github.com/aws-cloudformation/cloudformation-guard/releases/download/3.0.0/cfn-guard-v3-ubuntu-latest.tar.gz -O - | tar -xzvf - -C ./cfn-guard-temp/ +RUN cp ./cfn-guard-temp/cfn-guard-v3-ubuntu-latest/cfn-guard /home/vscode/.local/bin/ +RUN rm -rf ./cfn-guard-temp/ \ No newline at end of file diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5dacdf0..029a746 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -82,3 +82,15 @@ jobs: - name: Lint run: | make lint + + - name: Install cfn-guard + # This is partially duplicated in .devcontainer/Dockerfile, with the copy target being the only difference + run: | + mkdir ./cfn-guard-temp/ + wget https://github.com/aws-cloudformation/cloudformation-guard/releases/download/3.0.0/cfn-guard-v3-ubuntu-latest.tar.gz -O - | tar -xzvf - -C ./cfn-guard-temp/ + cp ./cfn-guard-temp/cfn-guard-v3-ubuntu-latest/cfn-guard ~/.local/bin/ + rm -rf ./cfn-guard-temp/ + + - name: Static Analysis - guard + run: | + make static-analysis-guard diff --git a/packages/aws-cloudformation/CHANGELOG.md b/packages/aws-cloudformation/CHANGELOG.md index 877ea5c..c699a97 100644 --- a/packages/aws-cloudformation/CHANGELOG.md +++ b/packages/aws-cloudformation/CHANGELOG.md @@ -10,9 +10,14 @@ What is in scope for breaking changes includes (but isn't necessarily limited to ## Changes -### (Unreleased) +### v0.2.0 + +- Restrict values for LogRetentionPolicy in the honeypot stack to the values log groups allow so there's feedback before stack creation +- Allow for injecting a KMS key into the honeypot stack to use for the new log group +- Switch to using managed policies instead of inline policies for the task and task execution roles - (Dev only change) Always use the latest Amazon Linux 2023 image for the basion host +- (Dev only change) Start using cfn-guard for security static analysis ### v0.1.1 diff --git a/packages/aws-cloudformation/Makefile b/packages/aws-cloudformation/Makefile index 53d7553..1ec9838 100644 --- a/packages/aws-cloudformation/Makefile +++ b/packages/aws-cloudformation/Makefile @@ -1,4 +1,10 @@ SHELL:=/bin/bash -O globstar # Needed to make sure the glob below finds file at the root of the folder lint: - cfn-lint ./templates/**/*.yaml \ No newline at end of file + cfn-lint ./templates/**/*.yaml +static-analysis-guard: # Only focusing on the templates that get published to consumers for now + cfn-guard validate \ + --rules ./guard-rules-registry-all-rules.guard \ + --data ./templates/honeypot.yaml \ + --data ./templates/honeypot-stack-policies.yaml \ + --show-summary all \ No newline at end of file diff --git a/packages/aws-cloudformation/guard-rules-registry-all-rules.guard b/packages/aws-cloudformation/guard-rules-registry-all-rules.guard new file mode 100644 index 0000000..14ccb4e --- /dev/null +++ b/packages/aws-cloudformation/guard-rules-registry-all-rules.guard @@ -0,0 +1,3227 @@ +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# S3_BUCKET_LOGGING_ENABLED +# +# Description: +# Checks whether logging is enabled for your S3 buckets. +# +# Reports on: +# AWS::S3::Bucket +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no S3 resource present +# b) PASS: when all S3 resources Logging Configuration exists +# c) FAIL: when all S3 resources have Logging Configuration is not set +# d) SKIP: when metadata includes the suppression for rule S3_BUCKET_LOGGING_ENABLED + +# +# Select all S3 resources from incoming template (payload) +# + +let s3_buckets_bucket_logging_enabled = Resources.*[ Type == 'AWS::S3::Bucket' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "S3_BUCKET_LOGGING_ENABLED" +] + +rule S3_BUCKET_LOGGING_ENABLED when %s3_buckets_bucket_logging_enabled !empty { + %s3_buckets_bucket_logging_enabled.Properties.LoggingConfiguration exists + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: S3 Bucket Logging needs to be configured to enable logging. + Fix: Set the S3 Bucket property LoggingConfiguration to start logging into S3 bucket. + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# S3_BUCKET_SERVER_SIDE_ENCRYPTION_ENABLED +# +# Description: +# Checks if your Amazon S3 bucket either has the Amazon S3 default encryption enabled or that the Amazon S3 bucket policy +# explicitly denies put-object requests without server side encryption that uses AES-256 or AWS Key Management Service. +# +# Reports on: +# AWS::S3::Bucket +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no S3 resource present +# b) PASS: when all S3 resources Bucket Encryption ServerSideEncryptionByDefault is set to either "aws:kms" or "AES256" +# c) FAIL: when all S3 resources have Bucket Encryption ServerSideEncryptionByDefault is not set or does not have "aws:kms" or "AES256" configurations +# d) SKIP: when metadata includes the suppression for rule S3_BUCKET_SERVER_SIDE_ENCRYPTION_ENABLED + +# +# Select all S3 resources from incoming template (payload) +# + +let s3_buckets_server_side_encryption = Resources.*[ Type == 'AWS::S3::Bucket' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "S3_BUCKET_SERVER_SIDE_ENCRYPTION_ENABLED" +] + +rule S3_BUCKET_SERVER_SIDE_ENCRYPTION_ENABLED when %s3_buckets_server_side_encryption !empty { + %s3_buckets_server_side_encryption.Properties.BucketEncryption exists + %s3_buckets_server_side_encryption.Properties.BucketEncryption.ServerSideEncryptionConfiguration[*].ServerSideEncryptionByDefault.SSEAlgorithm in ["aws:kms","AES256"] + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: S3 Bucket must enable server-side encryption. + Fix: Set the S3 Bucket property BucketEncryption.ServerSideEncryptionConfiguration.ServerSideEncryptionByDefault.SSEAlgorithm to either "aws:kms" or "AES256" + >> +} + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# S3_DEFAULT_ENCRYPTION_KMS +# +# Description: +# Checks whether the Amazon S3 buckets are encrypted with AWS Key Management Service(AWS KMS). +# The rule is NON_COMPLIANT if the Amazon S3 bucket is not encrypted with AWS KMS key. +# +# Reports on: +# AWS::S3::Bucket +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no S3 resource present +# b) PASS: when all S3 resources have ServerSideEncryptionConfiguration property set with values of "aws:kms" or "AES256" +# c) FAIL: when all S3 resources have ServerSideEncryptionConfiguration property not set or values are not "aws:kms" or "AES256" +# d) SKIP: when metadata includes the suppression for rule S3_DEFAULT_ENCRYPTION_KMS + +# +# Assignments +# +let s3_buckets_s3_default_encryption = Resources.*[ Type == 'AWS::S3::Bucket' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "S3_DEFAULT_ENCRYPTION_KMS" +] + +rule S3_DEFAULT_ENCRYPTION_KMS when %s3_buckets_s3_default_encryption !empty { + %s3_buckets_s3_default_encryption.Properties.BucketEncryption exists + %s3_buckets_s3_default_encryption.Properties.BucketEncryption.ServerSideEncryptionConfiguration[*].ServerSideEncryptionByDefault.SSEAlgorithm in ["aws:kms","AES256"] + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: S3 Bucket default encryption must be set. + Fix: Set the S3 Bucket property BucketEncryption.ServerSideEncryptionConfiguration.ServerSideEncryptionByDefault.SSEAlgorithm to either "aws:kms" or "AES256" + >> +} + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# S3_BUCKET_DEFAULT_LOCK_ENABLED +# +# Description: +# Checks whether Amazon S3 bucket has lock enabled, by default +# +# Reports on: +# AWS::S3::Bucket +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no S3 resource present +# b) PASS: when all S3 resources ObjectLockEnabled property is set to true +# c) FAIL: when all S3 resources do not have the ObjectLockEnabled property is set to true or is missing +# d) SKIP: when metada has rule suppression for S3_BUCKET_DEFAULT_LOCK_ENABLED + +# +# Select all S3 resources from incoming template (payload) +# +let s3_buckets_default_lock_enabled = Resources.*[ Type == 'AWS::S3::Bucket' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "S3_BUCKET_DEFAULT_LOCK_ENABLED" +] + +rule S3_BUCKET_DEFAULT_LOCK_ENABLED when %s3_buckets_default_lock_enabled !empty { + %s3_buckets_default_lock_enabled.Properties.ObjectLockEnabled exists + %s3_buckets_default_lock_enabled.Properties.ObjectLockEnabled == true + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: S3 Bucket ObjectLockEnabled must be set to true. + Fix: Set the S3 property ObjectLockEnabled parameter to true. + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# S3_BUCKET_PUBLIC_READ_PROHIBITED +# +# Description: +# Checks if your Amazon S3 buckets do not allow public read access. The rule checks the Block Public +# Access settings, the bucket policy, and the bucket access control list (ACL). +# +# Reports on: +# AWS::S3::Bucket +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no S3 resource present +# b) PASS: when all S3 resources Public Access Block Configuration element is present and properties are set to true +# c) FAIL: when all S3 resources do not have the Public Access Block Configuration element present or all properties set to true +# d) SKIP: when metadata includes the suppression for rule S3_BUCKET_PUBLIC_READ_PROHIBITED + +# +# Select all S3 resources from incoming template (payload) +# +let s3_bucket_public_read_prohibited = Resources.*[ Type == 'AWS::S3::Bucket' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "S3_BUCKET_PUBLIC_READ_PROHIBITED" +] + +rule S3_BUCKET_PUBLIC_READ_PROHIBITED when %s3_bucket_public_read_prohibited !empty { + %s3_bucket_public_read_prohibited.Properties.PublicAccessBlockConfiguration exists + %s3_bucket_public_read_prohibited.Properties.PublicAccessBlockConfiguration.BlockPublicAcls == true + %s3_bucket_public_read_prohibited.Properties.PublicAccessBlockConfiguration.BlockPublicPolicy == true + %s3_bucket_public_read_prohibited.Properties.PublicAccessBlockConfiguration.IgnorePublicAcls == true + %s3_bucket_public_read_prohibited.Properties.PublicAccessBlockConfiguration.RestrictPublicBuckets == true + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: S3 Bucket Public Write Access controls need to be restricted. + Fix: Set S3 Bucket PublicAccessBlockConfiguration properties for BlockPublicAcls, BlockPublicPolicy, IgnorePublicAcls, RestrictPublicBuckets parameters to true. + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# S3_BUCKET_SSL_REQUESTS_ONLY +# +# Description: +# Checks if Amazon S3 buckets have policies that require requests to use Secure Socket Layer (SSL). +# +# Reports on: +# AWS::S3::BucketPolicy +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no S3 Bucket Policy Document resource present +# b) PASS: when all S3 Bucket Policy Document set to deny if condition SecureTransport not true +# c) FAIL: when all S3 Bucket Policy Document does not have deny on insecure transport actions +# d) SKIP: when metadata includes the suppression for rule S3_BUCKET_SSL_REQUESTS_ONLY + +# +# Select all S3 resources from incoming template (payload) +# +let s3_buckets_policies_ssl_requests_only = Resources.*[ Type == 'AWS::S3::BucketPolicy' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "S3_BUCKET_SSL_REQUESTS_ONLY" +] + +rule S3_BUCKET_SSL_REQUESTS_ONLY when %s3_buckets_policies_ssl_requests_only !empty { + some %s3_buckets_policies_ssl_requests_only.Properties.PolicyDocument.Statement.* == {"Action":"s3:*","Effect":"Deny","Principal":"*","Resource":"*","Condition":{"Bool":{"aws:SecureTransport":false}}} + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: Bucket policies must feature a statement to enforce TLS usage. + Fix: Set a bucket policy statement to '"Action":"s3:*","Effect":"Deny","Principal":"*","Resource":"*","Condition":{"Bool":{"aws:SecureTransport":false}}' . + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# S3_BUCKET_PUBLIC_WRITE_PROHIBITED +# +# Description: +# Checks if your Amazon S3 buckets do not allow public write access. The rule checks the Block Public +# Access settings, the bucket policy, and the bucket access control list (ACL). +# +# Reports on: +# AWS::S3::Bucket +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no S3 resource present +# b) PASS: when all S3 resources Public Access Block Configuration element is present and properties are set to true +# c) FAIL: when all S3 resources do not have the Public Access Block Configuration element present or all properties set to true +# d) SKIP: when metadata includes the suppression for rule S3_BUCKET_PUBLIC_WRITE_PROHIBITED + +# +# Select all S3 resources from incoming template (payload) +# +let s3_buckets_public_write_prohibited = Resources.*[ Type == 'AWS::S3::Bucket' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "S3_BUCKET_PUBLIC_WRITE_PROHIBITED" +] + +rule S3_BUCKET_PUBLIC_WRITE_PROHIBITED when %s3_buckets_public_write_prohibited !empty { + %s3_buckets_public_write_prohibited.Properties.PublicAccessBlockConfiguration exists + %s3_buckets_public_write_prohibited.Properties.PublicAccessBlockConfiguration.BlockPublicAcls == true + %s3_buckets_public_write_prohibited.Properties.PublicAccessBlockConfiguration.BlockPublicPolicy == true + %s3_buckets_public_write_prohibited.Properties.PublicAccessBlockConfiguration.IgnorePublicAcls == true + %s3_buckets_public_write_prohibited.Properties.PublicAccessBlockConfiguration.RestrictPublicBuckets == true + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: S3 Bucket Public Write Access controls need to be restricted. + Fix: Set S3 Bucket PublicAccessBlockConfiguration properties for BlockPublicAcls, BlockPublicPolicy, IgnorePublicAcls, RestrictPublicBuckets parameters to true. + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# S3_BUCKET_VERSIONING_ENABLED +# +# Description: +# Checks if versioning is enabled for your S3 buckets. +# +# Reports on: +# AWS::S3::Bucket +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no S3 resource present +# b) PASS: when all S3 resources Versioning Configuration status is set to Enabled +# c) FAIL: when all S3 resources have Versioning Configuration status property not set or set to Suspended +# d) SKIP: when metadata includes the suppression for rule S3_BUCKET_VERSIONING_ENABLED + +# +# Select all S3 resources from incoming template (payload) +# +let s3_buckets_versioning_enabled = Resources.*[ Type == 'AWS::S3::Bucket' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "S3_BUCKET_VERSIONING_ENABLED" +] + +rule S3_BUCKET_VERSIONING_ENABLED when %s3_buckets_versioning_enabled !empty { + %s3_buckets_versioning_enabled.Properties.VersioningConfiguration exists + %s3_buckets_versioning_enabled.Properties.VersioningConfiguration.Status == 'Enabled' + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: S3 Bucket Versioning must be enabled. + Fix: Set the S3 Bucket property VersioningConfiguration.Status to 'Enabled' . + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# S3_BUCKET_REPLICATION_ENABLED +# +# Description: +# Checks whether the Amazon S3 buckets have cross-region replication enabled. +# +# Reports on: +# AWS::S3::Bucket +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no S3 resource present +# b) PASS: when all S3 resources replication configuration set status is set to Enabled +# c) FAIL: when all S3 resources have Versioning Configuration status property not set or set to Suspended +# d) SKIP: when metadata includes the suppression for rule S3_BUCKET_REPLICATION_ENABLED + +# +# Select all S3 resources from incoming template (payload) +# + +let s3_buckets_replication_enabled = Resources.*[ Type == 'AWS::S3::Bucket' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "S3_BUCKET_REPLICATION_ENABLED" +] + +rule S3_BUCKET_REPLICATION_ENABLED when %s3_buckets_replication_enabled !empty { + %s3_buckets_replication_enabled.Properties.ReplicationConfiguration exists + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: S3 Bucket replication should be enabled. + Fix: Set S3 Bucket ReplicationConfiguration to another S3 Bucket. + >> + ## TODO regex to identify cross-region +} +## Config Rule Name : s3-bucket-policy-grantee-check +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/s3-bucket-policy-grantee-check.html + +# Rule Intent: Checks that the access granted by the Amazon S3 bucket is restricted by any of the AWS principals, federated users, service principals, IP addresses, or VPCs that you provide. + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# S3_BUCKET_LEVEL_PUBLIC_ACCESS_PROHIBITED +# +# Description: +# Checks if Amazon Simple Storage Service (Amazon S3) buckets are publicly accessible. +# +# Reports on: +# AWS::S3::Bucket +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no S3 resource present +# b) PASS: when all S3 resources Public Access Block Configuration element is present and properties are set to true +# c) FAIL: when all S3 resources do not have the Public Access Block Configuration element present or all properties set to true +# d) SKIP: when metada has rule suppression for S3_BUCKET_LEVEL_PUBLIC_ACCESS_PROHIBITED + +# +# Select all S3 resources from incoming template (payload) +# +let s3_buckets_level_public_access_prohibited = Resources.*[ Type == 'AWS::S3::Bucket' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "S3_BUCKET_LEVEL_PUBLIC_ACCESS_PROHIBITED" +] + +rule S3_BUCKET_LEVEL_PUBLIC_ACCESS_PROHIBITED when %s3_buckets_level_public_access_prohibited !empty { + %s3_buckets_level_public_access_prohibited.Properties.PublicAccessBlockConfiguration exists + %s3_buckets_level_public_access_prohibited.Properties.PublicAccessBlockConfiguration.BlockPublicAcls == true + %s3_buckets_level_public_access_prohibited.Properties.PublicAccessBlockConfiguration.BlockPublicPolicy == true + %s3_buckets_level_public_access_prohibited.Properties.PublicAccessBlockConfiguration.IgnorePublicAcls == true + %s3_buckets_level_public_access_prohibited.Properties.PublicAccessBlockConfiguration.RestrictPublicBuckets == true + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: S3 Bucket Public Access controls need to be restricted. + Fix: Set S3 Bucket PublicAccessBlockConfiguration properties for BlockPublicAcls, BlockPublicPolicy, IgnorePublicAcls, RestrictPublicBuckets parameters to true. + >> +} +## Config Rule Name : elb-acm-certificate-required +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/elb-acm-certificate-required.html" + +## Config Rule Name : elb-cross-zone-load-balancing-enabled +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/elb-cross-zone-load-balancing-enabled.html" + +## Config Rule Name : elb-tls-https-listeners-only +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/elb-tls-https-listeners-only.html" + +## Config Rule Name : elb-logging-enabled +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/elb-logging-enabled.html" + +## Config Rule Name : elb-deletion-protection-enabled +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/elb-deletion-protection-enabled.html" + +## Config Rule Name : elb-predefined-security-policy-ssl-check +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/elb-predefined-security-policy-ssl-check.html" + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# EFS_ENCRYPTED_CHECK +# +# Description: +# Checks if Amazon Elastic File System (Amazon EFS) is configured to encrypt the file data +# using AWS Key Management Service (AWS KMS). The rule is NON_COMPLIANT if the encrypted +# key is set to false on DescribeFileSystems or if the KmsKeyId key on DescribeFileSystems +# does not match the KmsKeyId parameter. +# +# Reports on: +# AWS::EFS::FileSystem +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no EFS resource present +# b) PASS: when all EFS resources have encrypted key property set to true +# c) FAIL: when all EFS resources have encrypted key property not set or set to false +# d) SKIP: when guard metadata states EFS_ENCRYPTED_CHECK to be suppressed + +# +# Select all EFS resources from incoming template (payload) +# +let efs_file_systems_encrypted_check = Resources.*[ Type == 'AWS::EFS::FileSystem' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "EFS_ENCRYPTED_CHECK" +] + +rule EFS_ENCRYPTED_CHECK when %efs_file_systems_encrypted_check !empty { + %efs_file_systems_encrypted_check.Properties.Encrypted == true + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: EFS filesystem must be encrypted. + Fix: Set the EFS Filesystem property Encrypted parameter to true. + >> +} + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# EFS_RESOURCES_PROTECTED_BY_BACKUP_PLAN +# +# Description: +# Checks if Amazon Elastic File System (Amazon EFS) File Systems are protected by a backup plan. +# The rule is NON_COMPLIANT if the EFS File System is not covered by a backup plan. +# +# Reports on: +# AWS::EFS::FileSystem +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no EFS resource present +# b) PASS: when all EFS resources have backup policy set to ENABLED +# c) FAIL: when all EFS resources have backup policy Status to anything but ENABLED +# d) SKIP: when guard metadata states EFS_RESOURCES_PROTECTED_BY_BACKUP_PLAN to be suppressed + +# +# Select all EFS resources from incoming template (payload) +# +let efs_file_systems_protected_by_backup_plan = Resources.*[ Type == 'AWS::EFS::FileSystem' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "EFS_RESOURCES_PROTECTED_BY_BACKUP_PLAN" +] + +rule EFS_RESOURCES_PROTECTED_BY_BACKUP_PLAN when %efs_file_systems_protected_by_backup_plan !empty { + %efs_file_systems_protected_by_backup_plan.Properties.BackupPolicy.Status == 'ENABLED' + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: EFS filesystem backup policy should be enabled. + Fix: Set the EFS Filesystem property BackupPolicy.Status parameter to ENABLED. + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# EKS_ENDPOINT_NO_PUBLIC_ACCESS +# +# Description: +# Checks whether Amazon Elastic Kubernetes Service (Amazon EKS) endpoint is not publicly accessible. +# +# Reports on: +# AWS::EKS::Cluster +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no EKS clusters present +# b) PASS: when all EKS cluster endpoints are not publicly accessible +# c) FAIL: when any EKS cluster endpoints are publicly accessible +# d) SKIP: when metada has rule suppression for EKS_ENDPOINT_NO_PUBLIC_ACCESS + +# +# Select all EKS cluster resources from incoming template (payload) +# + +let amazon_eks_clusters_endpoint_no_public_access = Resources.*[ Type == 'AWS::EKS::Cluster' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "EKS_ENDPOINT_NO_PUBLIC_ACCESS" +] + +rule EKS_ENDPOINT_NO_PUBLIC_ACCESS when %amazon_eks_clusters_endpoint_no_public_access !empty { + # ensure the optional parameter is specified in the template + %amazon_eks_clusters_endpoint_no_public_access.Properties.ResourcesVpcConfig.EndpointPublicAccess EXISTS + # ensure the parameter is set to false + %amazon_eks_clusters_endpoint_no_public_access.Properties.ResourcesVpcConfig.EndpointPublicAccess == false + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: EKS endpoint public access is not allowed. + Fix: Set the boolean parameter ResourcesVpcConfig.EndpointPublicAccess to false + >> +} + ## Config Rule Name : codebuild-project-envvar-awscred-check + ## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/codebuild-project-envvar-awscred-check.html" + + ## Config Rule Name : codebuild-project-source-repo-url-check + ## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/codebuild-project-source-repo-url-check.html" + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# SUBNET_AUTO_ASSIGN_PUBLIC_IP_DISABLED +# +# Description: +# Checks if Amazon Virtual Private Cloud (Amazon VPC) subnets are assigned a public IP address. +# +# Reports on: +# AWS::EC2::Subnet +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no EC2 Subnet resource present +# b) PASS: when all EC2 Subnet resources have the MapPublicIpOnLaunch property set to false or it is missing (default false) +# c) FAIL: when any EC2 Subnet resources have the MapPublicIpOnLaunch property set to true +# d) SKIP: hen metadata includes the suppression for rule SUBNET_AUTO_ASSIGN_PUBLIC_IP_DISABLED + +# +# Select all EC2 Subnet resources from incoming template (payload) +# +let ec2_subnets_auto_assign_public_ip_disabled = Resources.*[ Type == 'AWS::EC2::Subnet' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "SUBNET_AUTO_ASSIGN_PUBLIC_IP_DISABLED" +] + +rule SUBNET_AUTO_ASSIGN_PUBLIC_IP_DISABLED when %ec2_subnets_auto_assign_public_ip_disabled !empty { + %ec2_subnets_auto_assign_public_ip_disabled.Properties.MapPublicIpOnLaunch !exists + OR %ec2_subnets_auto_assign_public_ip_disabled.Properties.MapPublicIpOnLaunch == false + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: VPCs should not have subnets that are assigned a public IP address. + Fix: remove the MapPublicIpOnLaucnh property or set it to false + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# RESTRICTED_INCOMING_TRAFFIC +# +# Description: +# Checks if the security groups in use do not allow unrestricted incoming TCP traffic to the specified ports. +# +# Reports on: +# AWS::EC2::SecurityGroup +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no Security Groups resource present +# b) SKIP when there are no TCP or UDP ingress rules +# c) PASS: when all Security Groups do no allow any of the restricted common ports +# d) FAIL: when a Security Group allows any of the restricted common ports +# e) SKIP: when metadata includes the suppression for rule RESTRICTED_INCOMING_TRAFFIC + +# +# Select all Security Group resources from incoming template (payload) +# +let aws_security_groups_restricted_incoming_traffic = Resources.*[ Type == 'AWS::EC2::SecurityGroup' + some Properties.SecurityGroupIngress[*] { + IpProtocol in ['tcp', 'udp'] + } + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "RESTRICTED_INCOMING_TRAFFIC" +] + +rule RESTRICTED_INCOMING_TRAFFIC when %aws_security_groups_restricted_incoming_traffic !empty { + let violations = Resources.*[ + Type == 'AWS::EC2::SecurityGroup' + some Properties.SecurityGroupIngress[*] { + FromPort in [ 20, 21, 3389, 3306, 4333 ] + ToPort in [ 20, 21, 3389, 3306, 4333 ] + } + ] + %violations empty + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: Security groups must not allow unrestricted incoming TCP/UDP traffic to the specified ports [20, 21, 3389, 3306, 4333]. + Fix: change the FromPort and ToPort properties in the SecurityGroupIngress list + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# EC2_INSTANCES_IN_VPC +# +# Description: +# Checks if your EC2 instances belong to a virtual private cloud (VPC). +# +# Reports on: +# AWS::EC2::Instance +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no EC2 resource present +# b) PASS: when all EC2 resources have the SubnetId property set +# c) FAIL: when any EC2 resources do not have the SubnetId property set +# d) SKIP: when metadata includes the suppression for rule EC2_INSTANCES_IN_VPC + +# +# Select all ECS Instance resources from incoming template (payload) +# +let ec2_instances_in_vpc = Resources.*[ Type == 'AWS::EC2::Instance' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "EC2_INSTANCES_IN_VPC" +] + +rule EC2_INSTANCES_IN_VPC when %ec2_instances_in_vpc !empty { + %ec2_instances_in_vpc.Properties.SubnetId !empty + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: EC2 Instances must belong to a VPC + Fix: set the SubnetId property to a subnet ID + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# EC2_INSTANCE_DETAILED_MONITORING_ENABLED +# +# Description: +# Checks if detailed monitoring is enabled for EC2 instances. +# +# Reports on: +# AWS::EC2::Instance +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no EC2 resource present +# b) PASS: when all EC2 resources have the Monitoring property set to true +# c) FAIL: when any EC2 resources do not have the Monitoring property set to true +# d) SKIP: hen metadata includes the suppression for rule EC2_INSTANCE_DETAILED_MONITORING_ENABLED + +# +# Select all EC2 Instance resources from incoming template (payload) +# +let ec2_instances_detailed_monitoring_enabled = Resources.*[ Type == 'AWS::EC2::Instance' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "EC2_INSTANCE_DETAILED_MONITORING_ENABLED" +] + +rule EC2_INSTANCE_DETAILED_MONITORING_ENABLED when %ec2_instances_detailed_monitoring_enabled !empty { + %ec2_instances_detailed_monitoring_enabled.Properties.Monitoring == true + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: EC2 Instance Monitoring must be enabled on all EC2 instances + Fix: set the Monitoring property to true + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# INCOMING_SSH_DISABLED +# +# Description: +# Checks if the incoming SSH traffic for the security groups is accessible. +# +# Reports on: +# AWS::EC2::SecurityGroup +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when no Security Group resources are present +# b) SKIP: when no SSH ingress is defined (port 22) +# c) PASS: when all Security Groups resources restrict the IP address of the incoming SSH traffic +# d) FAIL: when a Security Group allows SSH traffic from any IP address (0.0.0.0/0). +# e) SKIP: hen metadata includes the suppression for rule INCOMING_SSH_DISABLED + +# +# Select all Security Group resources from incoming template (payload) +# +let aws_security_groups_restricted_ssh = Resources.*[ + Type == 'AWS::EC2::SecurityGroup' + some Properties.SecurityGroupIngress[*] { + ToPort == 22 + FromPort == 22 + IpProtocol == "tcp" + } + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "INCOMING_SSH_DISABLED" +] + +rule INCOMING_SSH_DISABLED when %aws_security_groups_restricted_ssh !empty { + %aws_security_groups_restricted_ssh.Properties.SecurityGroupIngress[*] != {CidrIp:"0.0.0.0/0", ToPort:22, FromPort:22, IpProtocol:"tcp"} + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: IP addresses of the incoming SSH traffic in the security groups are restricted (CIDR other than 0.0.0.0/0) + Fix: set SecurityGroupIngress.CidrIp property to a more restrictive CIDR than 0.0.0.0/0 + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# EC2_INSTANCE_PROFILE_ATTACHED +# +# Description: +# Checks if an Amazon Elastic Compute Cloud (Amazon EC2) instance has an Identity and Access Management (IAM) profile attached to it. +# +# Reports on: +# AWS::EC2::Instance +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when no EC2 Instance resources are present +# b) PASS: when all EC2 Instace resources have an associated IAM instance profile +# d) FAIL: when any EC2 Instace resources do not have an associated IAM instance profile +# e) SKIP: hen metadata includes the suppression for rule EC2_INSTANCE_PROFILE_ATTACHED + +# +# Select all EC2 Instance resources from incoming template (payload) +# +let ec2_instances_profile_attached = Resources.*[ Type == 'AWS::EC2::Instance' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "EC2_INSTANCE_PROFILE_ATTACHED" +] + +rule EC2_INSTANCE_PROFILE_ATTACHED when %ec2_instances_profile_attached !empty { + %ec2_instances_profile_attached.Properties.IamInstanceProfile EXISTS + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: EC2 Instances must have IAM profile attached to it. + Fix: Associate the EC2 Instance property IamInstanceProfile with an IAM Instance Profile. + >> +} + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# NO_UNRESTRICTED_ROUTE_TO_IGW +# +# Description: +# Checks if there are public routes in the route table to an Internet Gateway (IGW). +# +# Reports on: +# AWS::EC2::Route +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when no EC2 Route resources are present +# b) SKIP: when there are no EC2 Routes to an Internet Gateway (no GatewayId property) +# c) PASS: when all EC2 Routes to an Internet Gateway have a restricted destination CIDR block (not '0.0.0.0/0' or '::/0') +# d) FAIL: when any EC2 Routes to an Internet Gateway have a destination CIDR block of '0.0.0.0/0' or '::/0' +# e) SKIP: hen metadata includes the suppression for rule NO_UNRESTRICTED_ROUTE_TO_IGW + +# +# Select all EC2 Route resources from incoming template (payload) +# +let routes_no_unrestricted_to_igw = Resources.*[ Type == 'AWS::EC2::Route' + Properties.GatewayId exists + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "NO_UNRESTRICTED_ROUTE_TO_IGW" +] + +rule NO_UNRESTRICTED_ROUTE_TO_IGW when %routes_no_unrestricted_to_igw !empty { + %routes_no_unrestricted_to_igw { + Properties { + DestinationCidrBlock not in ['0.0.0.0/0', '::/0'] + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: EC2 Routes to an IGW cannot have a destination CIDR block of '0.0.0.0/0' or '::/0' + Fix: Remove routes to an IGW (with the GatewayId property defined) or modify the DestinationCidrBlock property to a more restricted CIDR block + >> + } + } +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# ENCRYPTED_VOLUMES +# +# Description: +# Checks if the EBS volumes that are in an attached state are encrypted. +# +# Reports on: +# AWS::EC2::Volume +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no EBS volume resources present +# b) PASS: when all EBS volumes have the KmsKeyId property set or the Encrypted property set to true +# c) FAIL: when any EC2 volumes do not have the KmsKeyId or Encrypted property set +# e) SKIP: hen metadata includes the suppression for rule ENCRYPTED_VOLUMES + +# +# Select all EC2 Instance resources from incoming template (payload) +# +let ebs_volumes_encrypted = Resources.*[ Type == 'AWS::EC2::Volume' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "ENCRYPTED_VOLUMES" +] + +rule ENCRYPTED_VOLUMES when %ebs_volumes_encrypted !empty { + %ebs_volumes_encrypted.Properties.KmsKeyId !empty + OR %ebs_volumes_encrypted.Properties.Encrypted == true + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: EBS volumes in an attached state must encrypted. + Fix: either set the KmsKeyId property to a key ID, key alias, key ARN, or alias ARN + or set the Encrypted property to true to encrypt the volume with the account default key or AWS managed key. + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# EC2_INSTANCE_NO_PUBLIC_IP +# +# Description: +# Checks whether Amazon Elastic Compute Cloud (Amazon EC2) instances have a public IP association. +# +# Reports on: +# AWS::EC2::Instance +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when no EC2 Instance resources are present +# b) SKIP: when no EC2 Instances have network interfaces defined +# c) PASS: when no EC2 Instances with network interfaces have associated public IP addresses +# d) FAIL: when any EC2 Instances with network interfaces have associated public IP addresses +# e) SKIP: hen metadata includes the suppression for rule EC2_INSTANCE_NO_PUBLIC_IP + +# +# Select all EC2 Instance resources from incoming template (payload) +# +let ec2_instances_no_public_ip = Resources.*[Type == 'AWS::EC2::Instance' + Properties.NetworkInterfaces[*] !empty + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "EC2_INSTANCE_NO_PUBLIC_IP" +] + +rule EC2_INSTANCE_NO_PUBLIC_IP when %ec2_instances_no_public_ip !empty { + %ec2_instances_no_public_ip.Properties.NetworkInterfaces[*] { + AssociatePublicIpAddress !exists OR + AssociatePublicIpAddress == false + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: EC2 Instances cannot have public IP addresses associated with their network interfaces + Fix: remove the AssociatePublicIpAddress property from NetworkInterfaces list or set it to false + >> + } +} + + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# EBS_OPTIMIZED_INSTANCE +# +# Description: +# Checks whether EBS optimization is enabled for your EC2 instances that can be EBS-optimized +# +# Reports on: +# AWS::EC2::Instance +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no EC2 resource present +# b) PASS: when all EC2 resources EbsOptimized property is set to true +# c) FAIL: when any EC2 resources do not have the EbsOptimized property set to true +# e) SKIP: hen metadata includes the suppression for rule EBS_OPTIMIZED_INSTANCE + +# +# Select all AWS EC2 Instance resources from incoming template (payload) +# +let ec2_ebs_optimized_instances = Resources.*[ Type == 'AWS::EC2::Instance' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "EBS_OPTIMIZED_INSTANCE" +] + +rule EBS_OPTIMIZED_INSTANCE when %ec2_ebs_optimized_instances !empty { + %ec2_ebs_optimized_instances.Properties.EbsOptimized == true + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: EBS optimization must be enabled for your EC2 instances + Fix: set the EbsOptimized property to true + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# EC2_EBS_ENCRYPTION_BY_DEFAULT +# +# Description: +# Check that Amazon Elastic Block Store (EBS) encryption is enabled by default +# Reports on: +# AWS::EC2::Volume +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when no EC2 Volume resources are present +# b) PASS: when all EC2 Volume resources have the Encrypted property set to true +# c) FAIL: when any EC2 Volumes resources do not have the Encrypted property set to true +# e) SKIP: when metadata includes the suppression for rule EC2_EBS_ENCRYPTION_BY_DEFAULT + +# +# Select all EC2 Volume resources from incoming template (payload) +# +let ec2_ebs_volumes_encrypted_by_default = Resources.*[ Type == 'AWS::EC2::Volume' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "EC2_EBS_ENCRYPTION_BY_DEFAULT" +] + +rule EC2_EBS_ENCRYPTION_BY_DEFAULT when %ec2_ebs_volumes_encrypted_by_default !empty { + %ec2_ebs_volumes_encrypted_by_default.Properties.Encrypted == true + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: All EBS Volumes should be encryped + Fix: Set Encrypted property to true + >> +} +## Config Rule Name : kms-cmk-not-scheduled-for-deletion +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/kms-cmk-not-scheduled-for-deletion.html" + +## Config Rule Name : cmk-backing-key-rotation-enabled +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/cmk-backing-key-rotation-enabled.html" + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# DMS_REPLICATION_NOT_PUBLIC +# +# Description: +# Checks whether AWS Database Migration Service replication instances are not set to allow public. +# +# Reports on: +# AWS::DMS::ReplicationInstance +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there is no DMS Replication Instance present +# b) FAIL: When DMS Replication Instance is present and PubliclyAccessible property is set to true +# c) PASS: When DMS Replication Instance is present and PubliclyAccessible property is set to false +# c) PASS: When DMS Replication Instance is present and PubliclyAccessible property is not set +# d) SKIP: when metada has rule suppression for DMS_REPLICATION_NOT_PUBLIC + +# +# Select all Redshift cluster resources from incoming template +# + +let dms_replication_instances = Resources.*[ Type == 'AWS::DMS::ReplicationInstance' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "DMS_REPLICATION_NOT_PUBLIC" +] + +rule DMS_REPLICATION_NOT_PUBLIC when %dms_replication_instances !empty { + %dms_replication_instances.Properties.PubliclyAccessible exists + %dms_replication_instances.Properties.PubliclyAccessible == false + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: AWS Database Migration Service replication instances should not be public. + Fix: Set the DMS Replication Instance property PubliclyAccessible parameter to true. + >> +} + ## Config Rule Name : wafv2-logging-enabled + ## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/wafv2-logging-enabled.html" + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# LAMBDA_DLQ_CHECK +# +# Description: +# Checks whether an AWS Lambda function is configured with a dead-letter queue. +# +# Reports on: +# AWS::Lambda::Function +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when no AWS Lambda functions are present +# b) PASS: when all AWS Lambda functions are configured with a dead-letter queue +# c) FAIL: when any AWS Lambda functions are not configured with a dead-letter queue +# d) SKIP: hen metadata includes the suppression for rule LAMBDA_DLQ_CHECK + +# +# Select all AWS Lambda Function resources from incoming template (payload) +# +let aws_lambda_functions_dlq = Resources.*[ Type == 'AWS::Lambda::Function' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "LAMBDA_DLQ_CHECK" +] + +rule LAMBDA_DLQ_CHECK when %aws_lambda_functions_dlq !empty { + %aws_lambda_functions_dlq.Properties.DeadLetterConfig.TargetArn !empty + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: All AWS Lambda Functions must have a dead-letter queue configured + Fix: Set the DeadLetterConfig.TargetAr Property to the Amazon Resource Name (ARN) of an Amazon SQS queue or Amazon SNS topic + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# LAMBDA_CONCURRENCY_CHECK +# +# Description: +# Checks whether the AWS Lambda function is configured with function-level concurrent execution limit. +# +# Reports on: +# AWS::Lambda::Function +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when no AWS Lambda functions are present +# b) PASS: when all AWS Lambda functions are configured with function-level concurrent execution limits +# c) FAIL: when any AWS Lambda functions are not configured with function-level concurrent execution limits +# d) SKIP: hen metadata includes the suppression for rule LAMBDA_CONCURRENCY_CHECK + +# +# Select all AWS Lambda Function resources from incoming template (payload) +# +let aws_lambda_functions_concurrency = Resources.*[ Type == 'AWS::Lambda::Function' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "LAMBDA_CONCURRENCY_CHECK" +] + +rule LAMBDA_CONCURRENCY_CHECK when %aws_lambda_functions_concurrency !empty { + %aws_lambda_functions_concurrency.Properties.ReservedConcurrentExecutions >= 0 + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: All AWS Lambda Functions must have concurrent execution limits configured + Fix: Set the ReservedConcurrentExecutions property to an integer greater than or equal to 0 + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# LAMBDA_FUNCTION_PUBLIC_ACCESS_PROHIBITED +# +# Description: +# Checks if the AWS Lambda function policy attached to the Lambda resource prohibits public access. +# +# Reports on: +# AWS::Lambda::Permission +# AWS::Lambda::LayerVersionPermission +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when no AWS Lambda permission policies are present +# b) PASS: when all AWS Lambda permission policies prohibit public access +# c) FAIL: when any AWS Lambda permission policies allow public access +# d) SKIP: hen metadata includes the suppression for rule LAMBDA_FUNCTION_PUBLIC_ACCESS_PROHIBITED + +# +# Select all AWS Lambda Permission resources from incoming template (payload) +# +let aws_lambda_permissions_public_access_prohibited = Resources.*[ + Type in [ /AWS::Lambda::Permission/, + /AWS::Lambda::LayerVersionPermission/ ] + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "LAMBDA_FUNCTION_PUBLIC_ACCESS_PROHIBITED" +] + +rule LAMBDA_FUNCTION_PUBLIC_ACCESS_PROHIBITED when %aws_lambda_permissions_public_access_prohibited !empty { + + # Lambda permission policy where principal is an account id + %aws_lambda_permissions_public_access_prohibited { + Type == 'AWS::Lambda::Permission' + Properties { + Principal in [ /^\d{12}$/, "AWS::AccountId" ] + OR Principal > 0 + } + } + + # Lambda permission policy where principal is a service (not s3) + OR %aws_lambda_permissions_public_access_prohibited { + Type == 'AWS::Lambda::Permission' + Properties { + Principal != 's3.amazonaws.com' + PrincipalOrgID !empty + OR SourceAccount exists + OR SourceArn !empty + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: All Lambda permission policies attached to Lambda resources must prohibit public access. + Fix: Limit permission policies by setting the Principal property to an account ID, + or limiting a service principal by setting the SourceArn, SourceAccount, or PrincipalOrgID properties. + >> + } + } + + # Lambda permission policy where principal is s3 service + OR %aws_lambda_permissions_public_access_prohibited { + Type == 'AWS::Lambda::Permission' + Properties { + Principal == 's3.amazonaws.com' + PrincipalOrgID !empty + OR SourceAccount exists + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: All Lambda permission policies attached to Lambda resources must prohibit public access. + Fix: Limit permission policies by setting the Principal property to an account ID, + or for S3 as the principal specify either a SourceAccount or PrincipalOrgID. + Note: It is possible for an S3 bucket to be deleted by its owner and recreated by another account. + >> + } + } + + # Lambda layer version permission policies + OR %aws_lambda_permissions_public_access_prohibited { + Type == 'AWS::Lambda::LayerVersionPermission' + Properties { + OrganizationId !empty + OR Principal in [ /^\d{12}$/, "AWS::AccountId" ] + OR Principal > 0 + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: All Lambda permission policies attached to Lambda resources must prohibit public access. + Fix: For Lambda layer version permission policies, either limit permissions by the OrganizationId property + or set the Principal property to an account ID rather than using a wildcard (*). + >> + } + } +} + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# LAMBDA_INSIDE_VPC +# +# Description: +# Checks whether an AWS Lambda function is allowed access to an Amazon Virtual Private Cloud. +# +# Reports on: +# AWS::Lambda::Function +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when no AWS Lambda functions are present +# b) PASS: when all AWS Lambda functions are VPC enabled +# c) FAIL: when any AWS Lambda functions are not VPC enabled +# d) SKIP: hen metadata includes the suppression for rule LAMBDA_INSIDE_VPC + +# +# Select all AWS Lambda Function resources from incoming template (payload) +# +let aws_lambda_functions_inside_vpc = Resources.*[ Type == 'AWS::Lambda::Function' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "LAMBDA_INSIDE_VPC" +] + +rule LAMBDA_INSIDE_VPC when %aws_lambda_functions_inside_vpc !empty { + %aws_lambda_functions_inside_vpc.Properties.VpcConfig.SecurityGroupIds !empty + %aws_lambda_functions_inside_vpc.Properties.VpcConfig.SubnetIds !empty + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: All AWS Lambda Functions must be configured with access to a VPC + Fix: set the VpcConfig.SecurityGroupIds and VpcConfig.SubnetIds parameters with a list of security groups and subnets. + Lambda creates an elastic network interface for each combination of security group and subnet in the function's VPC configuration. + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# CLOUDWATCH_LOG_GROUP_ENCRYPTED +# +# Description: +# Checks if a log group in Amazon CloudWatch Logs is encrypted with a +# AWS Key Management Service (KMS) managed Customer Master Keys (CMK). +# +# Reports on: +# AWS::Logs::LogGroup +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no cloudwatch logs log group resources present +# b) PASS: when all cloudwatch logs log group resources property KmsKeyId is set +# c) FAIL: when all cloudwatch logs log group resources property KmsKeyId is not set with valid value +# d) SKIP: when metada has rule suppression for CLOUDWATCH_LOG_GROUP_ENCRYPTED + +# +# Select all cloudwatch logs log group resources from incoming template (payload) +# +let cloudwatch_logs = Resources.*[ Type == 'AWS::Logs::LogGroup' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "CLOUDWATCH_LOG_GROUP_ENCRYPTED" +] + +rule CLOUDWATCH_LOG_GROUP_ENCRYPTED when %cloudwatch_logs !empty { + %cloudwatch_logs.Properties.KmsKeyId exists + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: CloudWatch Log LogsGroup does not have KmsKeyId set. + Fix: Set the KmsKeyId parameter to a ARN. + >> +} + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# CLOUDWATCH_ALARM_ACTION_CHECK +# +# Description: +# Checks whether CloudWatch alarms have at least one alarm action, +# one Insufficient Data Actions action, or one OK action enabled. +# +# Reports on: +# AWS::Logs::LogGroup +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no cloudwatch alarm resources present +# b) PASS: when resource Metadata is set with rule suppressed +# c) PASS: when all cloudwatch alarm resources property Alarm Actions, Insufficient Data Actions, or OK Action set +# d) FAIL: when all cloudwatch alarms resources property Alarm Actions, Insufficient Data Actions, or OK Action are not set with valid value +# e) SKIP: when metada has rule suppression for CLOUDWATCH_ALARM_ACTION_CHECK + +# +# Select all cloudwatch logs log group resources from incoming template (payload) +# +let cloudwatch_alarm_action_check = Resources.*[ Type == 'AWS::CloudWatch::Alarm' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "CLOUDWATCH_ALARM_ACTION_CHECK" +] + +rule CLOUDWATCH_ALARM_ACTION_CHECK when %cloudwatch_alarm_action_check !empty { + %cloudwatch_alarm_action_check.Properties.AlarmActions exists or + %cloudwatch_alarm_action_check.Properties.OKActions exists or + %cloudwatch_alarm_action_check.Properties.InsufficientDataActions exists + + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: CloudWatch Alarms should have at least one Alarm Action, one Insufficient Data Actions action, or one OK Action enabled. + Fix: Set one Alarm Action, one Insufficient Data Actions action, or one OK Action on the CloudWatch Alarm resource. + >> +} + + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# CW_LOGGROUP_RETENTION_PERIOD_CHECK +# +# Description: +# Checks whether Amazon CloudWatch LogGroup retention +# period is set to specific number of days. +# +# Reports on: +# AWS::Logs::LogGroup +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no cloudwatch logs log group resources present +# b) PASS: when all cloudwatch logs log group resources property RetentionInDays is set +# c) FAIL: when all cloudwatch logs log group resources property RetentionInDays is not set with valid value +# d) SKIP: when metada has rule suppression for CW_LOGGROUP_RETENTION_PERIOD_CHECK + +# +# Select all cloudwatch logs log group resources from incoming template (payload) +# +let cloudwatch_logs_retention_period = Resources.*[ Type == 'AWS::Logs::LogGroup' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "CW_LOGGROUP_RETENTION_PERIOD_CHECK" +] + +rule CW_LOGGROUP_RETENTION_PERIOD_CHECK when %cloudwatch_logs_retention_period !empty { + %cloudwatch_logs_retention_period.Properties.RetentionInDays IN [1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, 3653] + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: CloudWatch Log LogsGroup does not have RetentionInDays set. + Fix: Set the RetentionInDays parameter to a value of 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, or 3653. + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# CLOUD_TRAIL_ENABLED +# +# Description: +# Checks if AWS CloudTrail is enabled. +# +# Reports on: +# AWS::CloudTrail::Trail +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no CloudTrail Trails present +# b) PASS: when all CloudTrail Trails have IsLogging parameter set true +# c) FAIL: when there are CloudTrail Trails with the IsLogging parameter is set to false +# d) FAIL: when there are CloudTrail Trails with IsLogging property not present +# e) SKIP: when metada has rule suppression for CLOUD_TRAIL_ENABLED + +# +# Select all CloudTrail Trail resources from incoming template (payload) +# +let cloudtrail_trails_enabled = Resources.*[ Type == 'AWS::CloudTrail::Trail' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "CLOUD_TRAIL_ENABLED" +] + +rule CLOUD_TRAIL_ENABLED when %cloudtrail_trails_enabled !empty { + %cloudtrail_trails_enabled.Properties.IsLogging EXISTS + %cloudtrail_trails_enabled.Properties.IsLogging == true + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: CloudTrail Trail should be enabled. + Fix: Set the IsLogging parameter to true. + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# MULTI_REGION_CLOUD_TRAIL_ENABLED +# +# Description: +# Checks if there is at least one multi-region AWS CloudTrail. +# +# Reports on: +# AWS::CloudTrail::Trail +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no CloudTrail Trails present +# b) PASS: when all CloudTrail Trails have IsMultiRegionTrail parameter set true +# c) FAIL: when there are CloudTrail Trails with the IsMultiRegionTrail parameter is set to false +# d) FAIL: when there are CloudTrail Trails with IsMultiRegionTrail property not present +# e) SKIP: when metada has rule suppression for MULTI_REGION_CLOUD_TRAIL_ENABLED + +# +# Select all CloudTrail Trail resources from incoming template (payload) +# +let cloudtrail_trails_multiregion = Resources.*[ Type == 'AWS::CloudTrail::Trail' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "MULTI_REGION_CLOUD_TRAIL_ENABLED" +] + +rule MULTI_REGION_CLOUD_TRAIL_ENABLED when %cloudtrail_trails_multiregion !empty { + %cloudtrail_trails_multiregion.Properties.IsMultiRegionTrail EXISTS + %cloudtrail_trails_multiregion.Properties.IsMultiRegionTrail == true + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: CloudTrail Trail should be set to log multiple regions. + Fix: Set the IsMultiRegionTrail parameter to true. + >> +} + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# CLOUD_TRAIL_LOG_FILE_VALIDATION_ENABLED +# +# Description: +# Checks whether AWS CloudTrail creates a signed digest file with logs. +# +# Reports on: +# AWS::CloudTrail::Trail +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no CloudTrail Trails present +# b) PASS: when all CloudTrail Trails have EnableLogFileValidation parameter set true +# c) FAIL: when there are CloudTrail Trails with the EnableLogFileValidation parameter is set to false +# d) FAIL: when there are CloudTrail Trails with EnableLogFileValidation property not present +# e) SKIP: when metada has rule suppression for CLOUD_TRAIL_LOG_FILE_VALIDATION_ENABLED + + +# +# Select all CloudTrail Trail resources from incoming template (payload) +# +let cloudtrail_trails_log_validation = Resources.*[ Type == 'AWS::CloudTrail::Trail' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "CLOUD_TRAIL_LOG_FILE_VALIDATION_ENABLED" +] + +rule CLOUD_TRAIL_LOG_FILE_VALIDATION_ENABLED when %cloudtrail_trails_log_validation !empty { + %cloudtrail_trails_log_validation.Properties.EnableLogFileValidation EXISTS + %cloudtrail_trails_log_validation.Properties.EnableLogFileValidation == true + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: CloudTrail Trail should have Log File Validation enabled. + Fix: Set the EnableLogFileValidation parameter to true. + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# CLOUDTRAIL_S3_DATAEVENTS_ENABLED +# +# Description: +# Checks whether at least one AWS CloudTrail trail is logging Amazon S3 data events for all S3 buckets. +# +# Reports on: +# AWS::CloudTrail::Trail +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no CloudTrail Trails present +# b) PASS: when all CloudTrail Trails have EventSelectors parameter set +# c) FAIL: when there are CloudTrail Trails with EventSelectors property not present +# d) SKIP: when metada has rule suppression for CLOUDTRAIL_S3_DATAEVENTS_ENABLED + +# +# Select all CloudTrail Trail resources from incoming template (payload) +# +let cloudtrail_trails_dataevents = Resources.*[ Type == 'AWS::CloudTrail::Trail' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "CLOUDTRAIL_S3_DATAEVENTS_ENABLED" +] + +rule CLOUDTRAIL_S3_DATAEVENTS_ENABLED when %cloudtrail_trails_dataevents !empty { + %cloudtrail_trails_dataevents.Properties.EventSelectors EXISTS + some %cloudtrail_trails_dataevents.Properties.EventSelectors.* == {DataResources:[{Type:'AWS::S3::Object',Values:['arn:aws:s3:::']}],IncludeManagementEvents:true,ReadWriteType:'All'} + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: CloudTrail Trail should have data events being logged. + Fix: Set the EventSelectors parameter to enable encryption. The value can be an alias name prefixed by "alias/", a fully specified ARN to an alias, a fully specified ARN to a key, or a globally unique identifier. + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# CLOUD_TRAIL_CLOUD_WATCH_LOGS_ENABLED +# +# Description: +# Checks whether AWS CloudTrail trails are configured to send logs to Amazon CloudWatch logs. +# The trail is non-compliant if the CloudWatchLogsLogGroupArn property of the trail is empty. +# +# Reports on: +# AWS::CloudTrail::Trail +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no CloudTrail Trails present +# b) PASS: when all CloudTrail Trails have CloudWatchLogsLogGroupArn parameter set +# c) FAIL: when there are CloudTrail Trails with CloudWatchLogsLogGroupArn property not present +# d) SKIP: when metada has rule suppression for CLOUD_TRAIL_CLOUD_WATCH_LOGS_ENABLED + +# +# Select all CloudTrail Trail resources from incoming template (payload) +# +let cloudtrail_trails_cw_logs_enabled = Resources.*[ Type == 'AWS::CloudTrail::Trail' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "CLOUD_TRAIL_CLOUD_WATCH_LOGS_ENABLED" +] + +rule CLOUD_TRAIL_CLOUD_WATCH_LOGS_ENABLED when %cloudtrail_trails_cw_logs_enabled !empty { + %cloudtrail_trails_cw_logs_enabled.Properties.CloudWatchLogsLogGroupArn exists + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: CloudTrail Trail should have logs exported to cloudwatch logs. + Fix: Set the CloudWatchLogsLogGroupArn parameter to enable exporting to CloudWatch Logs. + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# CLOUD_TRAIL_ENCRYPTION_ENABLED +# +# Description: +# Checks if AWS CloudTrail is configured to use the server side encryption (SSE) +# AWS Key Management Service KMS key encryption. +# +# Reports on: +# AWS::CloudTrail::Trail +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no CloudTrail Trails present +# b) PASS: when all CloudTrail Trails have KMSKeyId parameter set +# c) FAIL: when there are CloudTrail Trails with KMSKeyId property not present +# d) SKIP: when metada has rule suppression for CLOUD_TRAIL_ENCRYPTION_ENABLED + +# +# Select all CloudTrail Trail resources from incoming template (payload) +# +let cloudtrail_trails_encryption = Resources.*[ Type == 'AWS::CloudTrail::Trail' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "CLOUD_TRAIL_ENCRYPTION_ENABLED" +] + +rule CLOUD_TRAIL_ENCRYPTION_ENABLED when %cloudtrail_trails_encryption !empty { + %cloudtrail_trails_encryption.Properties.KMSKeyId EXISTS + %cloudtrail_trails_encryption.Properties.KMSKeyId is_string + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: CloudTrail Trail should be used to encrypt logs delivered by CloudTrail. + Fix: Set the KMSKeyId parameter to enable encryption. The value can be an alias name prefixed by "alias/", a fully specified ARN to an alias, a fully specified ARN to a key, or a globally unique identifier. + >> +} +## Config Rule Name : sns-encrypted-kms +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/sns-encrypted-kms.html" + +## Config Rule Name : elbv2-acm-certificate-required +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/elbv2-acm-certificate-required.html" + +## Config Rule Name : alb-http-drop-invalid-header-enabled +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/alb-http-drop-invalid-header-enabled.html" + +## Config Rule Name : alb-waf-enabled +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/alb-waf-enabled.html" + +## Config Rule Name : alb-http-to-https-redirection-check +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/alb-http-to-https-redirection-check.html" + +# Rule Intent: Checks if HTTP to HTTPS redirection is configured on all HTTP listeners of Application Load Balancers. + +# Expectations: +# a) SKIP: when there are no ALB resources present +# b) PASS: when one or more HTTP listeners have forwarding to an HTTPS listener +# c) FAIL: when one of more HTTP listeners have forwarding to an HTTP listener instead of redirection. +# d) FAIL: when one or more HTTP listeners of Application Load Balancer do not have HTTP to HTTPS redirection configured. + + + +# +# Select all ALB resources from incoming template (payload) +# + +## Config Rule Name : fsx-resources-protected-by-backup-plan +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/fsx-resources-protected-by-backup-plan.html" + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# API_GW_CACHE_ENABLED_AND_ENCRYPTED +# +# Description: +# Checks that all methods in Amazon API Gateway stages have cache enabled and cache encrypted. +# +# Reports on: +# AWS::ApiGateway::Stage +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no API GW Stage Methods present +# b) PASS: when all API Stage Method has caching enabled and encrypted +# c) FAIL: when API Stage Method does not have caching enabled and encrypted +# d) SKIP: when metadata includes the suppression for rule API_GW_CACHE_ENABLED_AND_ENCRYPTED + +let api_gw_cache_enabled_encrypted = Resources.*[ Type == 'AWS::ApiGateway::Stage' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "API_GW_CACHE_ENABLED_AND_ENCRYPTED" +] + +rule API_GW_CACHE_ENABLED_AND_ENCRYPTED when %api_gw_cache_enabled_encrypted !empty { + when %api_gw_cache_enabled_encrypted.Properties.MethodSettings exists { + %api_gw_cache_enabled_encrypted.Properties.MethodSettings.*.CacheDataEncrypted == true + %api_gw_cache_enabled_encrypted.Properties.MethodSettings.*.CachingEnabled == true + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: API Gateway Stage Method not set with caching and caching encrypted + Fix: API GW Stage Method property CacheDataEncrypted and CachingEnabled set to true + >> + } +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# API_GW_EXECUTION_LOGGING_ENABLED +# +# Description: +# Checks that all methods in Amazon API Gateway stage has logging enabled. The rule is NON_COMPLIANT if logging is not enabled. +# +# Reports on: +# AWS::ApiGateway::Stage +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no API GW Stage present +# b) PASS: when all API GW Stage Methods have logginglevel set to "ERROR" OR "INFO" +# c) FAIL: when API GW Domain Names doesn't have logginglevel set to "ERROR" OR "INFO" +# d) SKIP: when metadata includes the suppression for rule API_GW_EXECUTION_LOGGING_ENABLED + +let api_gw_execution_logging_enabled = Resources.*[ Type == 'AWS::ApiGateway::Stage' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "API_GW_EXECUTION_LOGGING_ENABLED" +] + +rule API_GW_EXECUTION_LOGGING_ENABLED when %api_gw_execution_logging_enabled !empty { + when %api_gw_execution_logging_enabled.Properties.MethodSettings !empty { + %api_gw_execution_logging_enabled.Properties.MethodSettings.*.LoggingLevel == "ERROR" OR + %api_gw_execution_logging_enabled.Properties.MethodSettings.*.LoggingLevel == "INFO" + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: Logging Level for API GW Method Setting not set + Fix: API GW Stage Method Setting logging level must be set to "ERROR" or "INFO" + >> + } +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# API_GW_ENDPOINT_TYPE_CHECK +# +# Description: +# Checks if Amazon API Gateway APIs are of the type specified in the rule parameter endpointConfigurationType +# +# Reports on: +# AWS::ApiGateway::DomainName +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no API GW present +# b) PASS: when all API GW have endpoint configuration set to "REGIONAL", "PRIVATE", and/or "EDGE" +# c) FAIL: when all API GW does not have endpoint configuration set to "REGIONAL", "PRIVATE", and/or "EDGE" +# d) SKIP: when metadata includes the suppression for rule API_GW_ENDPOINT_TYPE_CHECK + +# +# Select all API GW Method resources from incoming template (payload) +# +let api_gw_resources_type_check = Resources.*[ Type == 'AWS::ApiGateway::DomainName' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "API_GW_ENDPOINT_TYPE_CHECK" +] + +rule API_GW_ENDPOINT_TYPE_CHECK when %api_gw_resources_type_check !empty { + some %api_gw_resources_type_check.Properties.EndpointConfiguration.Types IN ["REGIONAL", "PRIVATE", "EDGE"] + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: EndpointConfiguration must contain "REGIONAL", "PRIVATE", and/or "EDGE" + Fix: Set EndpointConfiguration Type to "REGIONAL", "PRIVATE", and/or "EDGE" + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# API_GW_DOMAIN_DENY_NON_TLS_TRAFFIC +# +# Description: +# All API GW Domain Name Resources must deny non-TLS traffic +# +# Reports on: +# AWS::ApiGateway::DomainName +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no API GW Methods present +# b) PASS: when all API GW Domain Names have a security policy configured to deny non-TLS traffic +# c) FAIL: when API GW Domain Names doesn't have a security policy configured to deny non-TLS traffic +# d) SKIP: when metadata includes the suppression for rule API_GW_DOMAIN_DENY_NON_TLS_TRAFFIC + +# +# Select all API GW Method resources from incoming template (payload) +# +let aws_apigw_domain_resources_tls_traffic = Resources.*[ Type == 'AWS::ApiGateway::DomainName' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "API_GW_DOMAIN_DENY_NON_TLS_TRAFFIC" +] + +rule API_GW_DOMAIN_DENY_NON_TLS_TRAFFIC when %aws_apigw_domain_resources_tls_traffic !empty { + %aws_apigw_domain_resources_tls_traffic.Properties.SecurityPolicy == "TLS_1_2" + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: API Gateway DomainName - SecurityPolicy must use TLS 1.2 + Fix: Set the SecurityPolicy property parameter to "TLS_1_2". + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# REDSHIFT_CLUSTER_PUBLIC_ACCESS_CHECK +# +# Description: +# Redshift cluster should not be publicly accessible on the internet. +# +# Reports on: +# AWS::EKS::Cluster +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there is no Redshift cluster present +# b) PASS: when Redshift Cluster resources do not have the publiclyAccessible property set (default false) +# c) PASS: when Redshift Cluster resources have the PubliclyAccessible property set to false +# d) FAIL: when any Redshift Cluster resources have the PubliclyAccessible property set to true +# e) SKIP: when metada includes the suppression for rule REDSHIFT_CLUSTER_PUBLIC_ACCESS_CHECK + +# +# Select all Redshift cluster resources from incoming template +# + +let aws_redshift_clusters_resources_public_access_check = Resources.*[ Type == 'AWS::Redshift::Cluster' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "REDSHIFT_CLUSTER_PUBLIC_ACCESS_CHECK" +] + + +rule REDSHIFT_CLUSTER_PUBLIC_ACCESS_CHECK when %aws_redshift_clusters_resources_public_access_check !empty { + %aws_redshift_clusters_resources_public_access_check.Properties.PubliclyAccessible not exists or + %aws_redshift_clusters_resources_public_access_check.Properties.PubliclyAccessible == false + + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: Redshift cluster should not be available to public. + Fix: Set the Redshift property PubliclyAccessible parameter to false. + >> +} + +#################################### +## Gherkin ## +##################################### +# Rule Identifier: +# REDSHIFT_CLUSTER_CONFIGURATION_CHECK +# +# Description: +# Checks whether Amazon Redshift clusters have the specified settings (Encrypted Only) +# +# Reports on: +# AWS::Redshift::Cluster +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no Redshift Cluster resource present +# b) PASS: when Redshift Cluster resources have the Encrypted property set to true +# c) FAIL: when any Redshift Cluster resources do not have Encrypted property set (default false) +# d) FAIL: when any Redshift Cluster resources have Encrypted property set to false +# e) SKIP: when metadata includes the suppression for rule REDSHIFT_CLUSTER_CONFIGURATION_CHECK + +# +# Select all Redshift Cluster resources from incoming template (payload) +# +let redhshift_clusters_configuration_check = Resources.*[ Type == 'AWS::Redshift::Cluster' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "REDSHIFT_CLUSTER_CONFIGURATION_CHECK" +] + +rule REDSHIFT_CLUSTER_CONFIGURATION_CHECK when %redhshift_clusters_configuration_check !empty { + %redhshift_clusters_configuration_check.Properties.Encrypted == true + + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: Amazon Redshift configuration should have encryption enabled + Fix: Set the Encrypted property to true + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# REDSHIFT_BACKUP_ENABLED +# +# Description: +# Checks that Amazon Redshift automated snapshots are enabled for clusters. +# +# Reports on: +# AWS::Redshift::Cluster +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no Redshift Cluster resource present +# b) PASS: when Redshift Cluster resources don't have the AutomatedSnapshotRetentionPeriod property set (default retention period is 1 day) +# c) PASS: when Redshift Cluster resources have the AutomatedSnapshotRetentionPeriod property set to greater than 0 +# d) FAIL: when any Redshift Cluster resources have the AutomatedSnapshotRetentionPeriod property set to 0 +# e) SKIP: when metadata includes the suppression for rule REDSHIFT_BACKUP_ENABLED + +# +# Select all Redshift Cluster resources from incoming template (payload) +# +let redhshift_backup_enabled_clusters = Resources.*[ Type == 'AWS::Redshift::Cluster' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "REDSHIFT_BACKUP_ENABLED" +] + +rule REDSHIFT_BACKUP_ENABLED when %redhshift_backup_enabled_clusters !empty { + %redhshift_backup_enabled_clusters.Properties.AutomatedSnapshotRetentionPeriod not exists + or %redhshift_backup_enabled_clusters.Properties.AutomatedSnapshotRetentionPeriod > 0 + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: Amazon Redshift automated snapshots must be enabled for clusters + Fix: Either remove the AutomatedSnapshotRetentionPeriod property (default retention period is 1 day) + Or set the AutomatedSnapshotRetentionPeriod property to an integer greater than 0 + >> +} +#################################### +## Gherkin ## +##################################### +# Rule Identifier: +# REDSHIFT_ENHANCED_VPC_ROUTING_ENABLED +# +# Description: +# Checks if Amazon Redshift cluster has 'enhancedVpcRouting' enabled. +# +# Reports on: +# AWS::Redshift::Cluster +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no Redshift Cluster resource present +# b) PASS: when Redshift Cluster resources have property EnhancedVpcRouting set to true +# c) FAIL: when any Redshift Cluster resources do not have EnhancedVpcRouting property set (defualt false) +# d) FAIL: when any Redshift Cluster resources have EnhancedVpcRouting property set to false +# e) SKIP: when metadata includes the suppression for rule REDSHIFT_ENHANCED_VPC_ROUTING_ENABLED + +# +# Select all Redshift Cluster resources from incoming template (payload) +# +let redhshift_enhanced_vpc_routing_enabled_clusters = Resources.*[ Type == 'AWS::Redshift::Cluster' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "REDSHIFT_ENHANCED_VPC_ROUTING_ENABLED" +] + +rule REDSHIFT_ENHANCED_VPC_ROUTING_ENABLED when %redhshift_enhanced_vpc_routing_enabled_clusters !empty { + %redhshift_enhanced_vpc_routing_enabled_clusters.Properties.EnhancedVpcRouting == true + + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: Enhanced VPC Routing must be enabled on Redshift clusters + Fix: set the EnhancedVpcRouting property to true + >> +} +#################################### +## Gherkin ## +##################################### +# Rule Identifier: +# REDSHIFT_CLUSTER_MAINTENANCESETTINGS_CHECK +# +# Description: +# Checks whether Amazon Redshift clusters have the specified maintenance settings (AllowVersionUpgrade, PreferredMaintenanceWindow, AutomatedSnapshotRetentionPeriod) +# +# Reports on: +# AWS::Redshift::Cluster +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no Redshift Cluster resource present +# b) PASS: when Redshift Cluster resources have properties PreferredMaintenanceWindow set, AllowVersionUpgrade either not set (default true) or set to true, and AutomatedSnapshotRetentionPeriod either not set (default 1 day) or set to greated than 0. +# c) FAIL: when any Redshift Cluster resources do not have PreferredMaintenanceWindow property set +# d) FAIL: when any Redshift Cluster resources have AllowVersionUpgrade property set to false +# e) FAIL: when any Redshift Cluster resources have AutomatedSnapshotRetentionPeriod property set to 0 +# f) SKIP: when metadata includes the suppression for rule REDSHIFT_CLUSTER_MAINTENANCESETTINGS_CHECK + +# +# Select all Redshift Cluster resources from incoming template (payload) +# +let redhshift_clusters_maintenancesettings_check = Resources.*[ Type == 'AWS::Redshift::Cluster' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "REDSHIFT_CLUSTER_MAINTENANCESETTINGS_CHECK" +] + +rule REDSHIFT_CLUSTER_MAINTENANCESETTINGS_CHECK when %redhshift_clusters_maintenancesettings_check !empty { + %redhshift_clusters_maintenancesettings_check.Properties.PreferredMaintenanceWindow exists + + %redhshift_clusters_maintenancesettings_check.Properties.AllowVersionUpgrade not exists or + %redhshift_clusters_maintenancesettings_check.Properties.AllowVersionUpgrade == true + + + %redhshift_clusters_maintenancesettings_check.Properties.AutomatedSnapshotRetentionPeriod not exists or + %redhshift_clusters_maintenancesettings_check.Properties.AutomatedSnapshotRetentionPeriod > 0 + + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: Amazon Redshift maintenance settings must be configured + Fix: set the PreferredMaintenanceWindow property, remove the AllowVersionUpgrade property (default true) or set it to true, and remove the AutomatedSnapshotRetentionPeriod property (default 1 day) or set it to greated than 0. + >> +} +## Config Rule Name : acm-certificate-expiration-check +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/acm-certificate-expiration-check.html" + +## Config Rule Name : backup-plan-min-frequency-and-min-retention-check +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/backup-plan-min-frequency-and-min-retention-check.html" + +# Rule Intent: All DynamoDB Tables must have SEE enabled + +# Expectations: +# a) SKIP: when there are no DynamoDB Tables present +# b) PASS: when all DynamoDB Tables are encrypted +# c) FAIL: when all DynamoDB Tables are not are encrypted + +# +# Select all DynamoDB Table resources from incoming template (payload) +# +let aws_dynamodb_table_resources = Resources.*[ Type == 'AWS::DynamoDB::Table' ] + + +rule DYNAMODB_TABLE_MUST_BE_ENCRYPTED when %aws_dynamodb_table_resources !empty { + %aws_dynamodb_table_resources.Properties.SSESpecification EXISTS + %aws_dynamodb_table_resources.Properties.SSESpecification.SSEEnabled == true + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + DynamoDB Table properties must include SSESpecificationDynamoDB and set SSEEnabled parameter to true + >> + +} +## Config Rule Name : dynamodb-table-encrypted-kms +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/dynamodb-table-encrypted-kms.html" + +## Config Rule Name : dynamodb-in-backup-plan +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/dynamodb-in-backup-plan.html" + + ## Config Rule Name : dynamodb-resources-protected-by-backup-plan + ## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/dynamodb-resources-protected-by-backup-plan.html" + +## Config Rule Name : dynamodb-autoscaling-enabled +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/dynamodb-autoscaling-enabled.html" + +## Config Rule Name : dynamodb-pitr-enabled +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/dynamodb-pitr-enabled.html" + +# Rule Intent: All DynamoDB Tables must have Point-In-Time-Recovery enabled + +# Expectations: +# a) SKIP: when there are no DynamoDB Tables present +# b) PASS: when all DynamoDB Tables have PITR enabled +# c) FAIL: when all DynamoDB Tables have PITR disabled + +# +# Select all DynamoDB Table resources from incoming template (payload) +# +let aws_dynamodb_table_resources = Resources.*[ Type == 'AWS::DynamoDB::Table' ] + + +rule DYNAMODB_PITR_ENABLED when %aws_dynamodb_table_resources !empty { + # Ensure ALL DynamoDB Tables have Point-In-Time-Recovery enabled + %aws_dynamodb_table_resources.Properties.PointInTimeRecoverySpecification.PointInTimeRecoveryEnabled == true + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: All DynamoDB Tables must have Point-In-Time-Recovery enabled. + Fix: Set the dynamodb table property PointInTimeRecoverySpecification.PointInTimeRecoveryEnabled to true. + >> +} + +## Config Rule Name : dynamodb-throughput-limit-check +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/dynamodb-throughput-limit-check.html" + +## Config Rule Name : api-gw-cache-enabled-and-encrypted +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/api-gw-cache-enabled-and-encrypted.html" + + ## Config Rule Name : api-gw-associated-with-waf + ## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/API_GW_ASSOCIATED_WITH_WAF.html" + +## Config Rule Name : api-gw-execution-logging-enabled +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/api-gw-execution-logging-enabled.html" + +## Config Rule Name : api-gw-ssl-enabled +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/api-gw-ssl-enabled.html" + +## Config Rule Name : sagemaker-notebook-no-direct-internet-access +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/sagemaker-notebook-no-direct-internet-access.html" + +## Config Rule Name : sagemaker-endpoint-configuration-kms-key-configured +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/sagemaker-endpoint-configuration-kms-key-configured.html" + +## Config Rule Name : sagemaker-notebook-instance-kms-key-configured +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/sagemaker-notebook-instance-kms-key-configured.html" + + ## Config Rule Name : autoscaling-launch-config-public-ip-disabled + ## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/AUTOSCALING_LAUNCH_CONFIG_PUBLIC_IP_DISABLED.html" + + ## Config Rule Name : autoscaling-group-elb-healthcheck-required + ## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/autoscaling-group-elb-healthcheck-required.html" +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# AUTOSCALING_GROUP_ELB_HEALTHCHECK_REQUIRED +# +# Description: +# Checks whether your Auto Scaling groups that are associated with a load balancer are using Elastic Load Balancing health checks. +# +# Reports on: +# AWS::AutoScaling::AutoScalingGroup +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no S3 resource present +# b) PASS: when all S3 resources ObjectLockEnabled property is set to true +# c) FAIL: when all S3 resources do not have the ObjectLockEnabled property is set to true or is missing +# d) SKIP: when metada has rule suppression for S3_BUCKET_DEFAULT_LOCK_ENABLED + +# +# Select all S3 resources from incoming template (payload) +# + + + + + + + + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# IAM_NO_INLINE_POLICY_CHECK +# +# Description: +# Checks that inline policy feature is not in use. +# +# Reports on: +# AWS::IAM::User +# AWS::IAM::Role +# AWS::IAM::Group +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no IAM Users, Roles, or Groups present +# b) PASS: when all IAM Users, Roles, or Groups present have no inline policies listed +# c) FAIL: when any IAM Users, Roles, or Groups present have inline policies listed +# d) SKIP: when metada has rule suppression for IAM_NO_INLINE_POLICY_CHECK + +# +# Select all IAM User, Role, and Group resources from incoming template (payload) +# +let aws_iam_entities_no_inline_policy = Resources.*[ + Type in [ /AWS::IAM::User/, + /AWS::IAM::Role/, + /AWS::IAM::Group/ ] + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "IAM_NO_INLINE_POLICY_CHECK" +] + +rule IAM_NO_INLINE_POLICY_CHECK when %aws_iam_entities_no_inline_policy !empty { + %aws_iam_entities_no_inline_policy.Properties.Policies empty + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: Inline policies are not allowed on IAM Users, Roles, or Groups. + Fix: Remove the Policies list property from any IAM Users, Roles, or Groups. + >> +} + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# IAM_POLICY_NO_STATEMENTS_WITH_FULL_ACCESS +# +# Description: +# Checks if AWS Identity and Access Management (IAM) policies grant permissions to all actions on individual AWS resources. +# +# Reports on: +# AWS::IAM::ManagedPolicy +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no IAM Managed Policies present +# b) PASS: when all IAM Managed Policies do not allows full access to at least 1 AWS service +# c) FAIL: when any IAM Managed Policies allows full access to at least 1 AWS service. +# d) SKIP: when metada has rule suppression for IAM_POLICY_NO_STATEMENTS_WITH_FULL_ACCESS + +# +# Select all IAM Managed Policy resources from incoming template (payload) +# +let aws_iam_managed_policies_no_statements_with_full_access = Resources.*[ Type == 'AWS::IAM::ManagedPolicy' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "IAM_POLICY_NO_STATEMENTS_WITH_FULL_ACCESS" +] + +rule IAM_POLICY_NO_STATEMENTS_WITH_FULL_ACCESS when %aws_iam_managed_policies_no_statements_with_full_access !empty { + let violations = Resources.*[ + Type == 'AWS::IAM::ManagedPolicy' + some Properties.PolicyDocument.Statement[*] { + some Action[*] in ["*", /^[a-zA-Z0-9]*:\*$/] + Effect == "Allow" + Resource == "*" + } + ] + %violations empty + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: One or more IAM Managed Policies allow full access to at least 1 AWS service + Fix: Remove policy statements that match {"Effect": "Allow", "Action": ":*" ... } or {"Effect": "Allow", "Action": "*" ... } + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# IAM_USER_NO_POLICIES_CHECK +# +# Description: +# Checks that none of your IAM users have policies attached. IAM users must inherit permissions from IAM groups or roles. +# +# Reports on: +# AWS::IAM::User +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no IAM Users present +# b) PASS: when all IAM Users do not have policies attached +# c) FAIL: when any IAM User have policies attached +# d) SKIP: when metada has rule suppression for IAM_USER_NO_POLICIES_CHECK + +# +# Select all IAM User resources from incoming template (payload) +# +let aws_iam_users_no_policies = Resources.*[ Type == 'AWS::IAM::User' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "IAM_USER_NO_POLICIES_CHECK" +] + +rule IAM_USER_NO_POLICIES_CHECK when %aws_iam_users_no_policies !empty { + %aws_iam_users_no_policies.Properties.Policies empty + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: Inline policies are not allowed on IAM Users. IAM users must inherit permissions from IAM groups or roles. + Fix: Remove the Policies list property from any IAM Users. + >> +} + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# IAM_POLICY_NO_STATEMENTS_WITH_ADMIN_ACCESS +# +# Description: +# Checks the IAM policies that you create for Allow statements that grant permissions to all actions on all resources. +# +# Reports on: +# AWS::IAM::Policy +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no IAM Policies present +# b) PASS: when all IAM Policies do not grant permissions to all actions on all resources +# c) FAIL: when any IAM Policies grant permissions to all actions on all resources +# d) SKIP: when metada has rule suppression for IAM_POLICY_NO_STATEMENTS_WITH_ADMIN_ACCESS + +# +# Select all IAM Policy resources from incoming template (payload) +# +let aws_iam_policies_no_statements_with_admin_access = Resources.*[ Type == 'AWS::IAM::Policy' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "IAM_POLICY_NO_STATEMENTS_WITH_ADMIN_ACCESS" +] + +rule IAM_POLICY_NO_STATEMENTS_WITH_ADMIN_ACCESS when %aws_iam_policies_no_statements_with_admin_access !empty { + let violations = Resources.*[ + Type == 'AWS::IAM::Policy' + some Properties.PolicyDocument.Statement[*] { + some Action[*] == "*" + Effect == "Allow" + Resource == "*" + } + ] + %violations empty + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: One or more IAM policies contain allow statements that grant permissions to all actions on all resources + Fix: Remove policy statements that match {"Effect": "Allow", "Action": "*", "Resource": "*"} + >> +} + + + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# RDS_ENHANCED_MONITORING_ENABLED +# +# Description: +# Checks whether enhanced monitoring is enabled for Amazon Relational Database Service (Amazon RDS) instances. +# +# Reports on: +# AWS::RDS::DBInstance +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no RDS instances present +# b) PASS: when all RDS instances have MonitoringInterval set to a value of 1, 5, 10, 15, 30, or 60 +# c) FAIL: when all RDS instances have MonitoringInterval set to 0 +# d) FAIL: when there are RDS instances with MonitoringInterval property is not present +# e) SKIP: when metadata includes the suppression for rule RDS_ENHANCED_MONITORING_ENABLED + + +# +# Select all RDS instance resources from incoming template (payload) +# + +let aws_rds_instances_enhanced_monitoring_enabled = Resources.*[ Type == 'AWS::RDS::DBInstance' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "RDS_ENHANCED_MONITORING_ENABLED" +] + + +rule RDS_ENHANCED_MONITORING_ENABLED when %aws_rds_instances_enhanced_monitoring_enabled !empty { + %aws_rds_instances_enhanced_monitoring_enabled.Properties.MonitoringInterval EXISTS + %aws_rds_instances_enhanced_monitoring_enabled.Properties.MonitoringInterval IN [1, 5, 10, 15, 30, 60] + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: RDS Instance enhanced monitoring required. + Fix: Specify a value of 1, 5, 10, 15, 30, or 60 for the parameter on the property MonitoringInterval. + >> +} + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# RDS_AUTOMATIC_MINOR_VERSION_UPGRADE_ENABLED +# +# Description: +# Checks whether storage encryption is enabled for your RDS DB instances +# +# Reports on: +# AWS::RDS::DBInstance +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no RDS instances present +# b) PASS: when all RDS instances have AutoMinorVersionUpgrade set to true +# c) FAIL: when all RDS instances have AutoMinorVersionUpgrade set to false +# d) FAIL: when there are RDS instances with AutoMinorVersionUpgrade property is not present +# e) SKIP: when metadata includes the suppression for rule RDS_AUTOMATIC_MINOR_VERSION_UPGRADE_ENABLED + +# +# Select all RDS instance resources from incoming template (payload) +# + +let aws_rds_instances_minor_version_upgrade_enabled = Resources.*[ Type == 'AWS::RDS::DBInstance' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "RDS_AUTOMATIC_MINOR_VERSION_UPGRADE_ENABLED" +] + + +rule RDS_AUTOMATIC_MINOR_VERSION_UPGRADE_ENABLED when %aws_rds_instances_minor_version_upgrade_enabled !empty { + %aws_rds_instances_minor_version_upgrade_enabled.Properties.AutoMinorVersionUpgrade EXISTS + %aws_rds_instances_minor_version_upgrade_enabled.Properties.AutoMinorVersionUpgrade == true + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: All RDS instances must have automatic minor version upgrade enabled. + Fix: Set the AutoMinorVersionUpgrade parameter to true. + >> +} + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# RDS_INSTANCE_PUBLIC_ACCESS_CHECK +# +# Description: +# Checks if an RDS instances has Publicly Accessible not set. +# +# Reports on: +# AWS::RDS::DBInstance +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no RDS instances present +# b) PASS: when all RDS instances have PubliclyAccessible set to true +# c) FAIL: when all RDS instances have PubliclyAccessible set to false +# d) FAIL: when there are RDS instances with PubliclyAccessible property is not present +# e) SKIP: when metadata includes the suppression for rule RDS_INSTANCE_PUBLIC_ACCESS_CHECK + +# +# Select all RDS instance resources from incoming template (payload) +# +let aws_rds_instances_not_public = Resources.*[ Type == 'AWS::RDS::DBInstance' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "RDS_INSTANCE_PUBLIC_ACCESS_CHECK" +] + +rule RDS_INSTANCE_PUBLIC_ACCESS_CHECK when %aws_rds_instances_not_public !empty { + # ALL RDS instances must have PubliclyAccessible set to false + %aws_rds_instances_not_public.Properties.PubliclyAccessible == false + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: All RDS instances must not be publicly accessible. + Fix: Set the PubliclyAccessible to false. + >> +} + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# RDS_INSTANCE_LOGGING_ENABLED +# +# Description: +# Checks if log types exported to Amazon CloudWatch for an Amazon Relational +# Database Service (Amazon RDS) instance are enabled. +# +# Reports on: +# AWS::RDS::DBInstance +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no RDS instances present +# b) PASS: when all RDS instances have EnableCloudwatchLogsExports set to true +# c) FAIL: when all RDS instances have EnableCloudwatchLogsExports set to false +# d) FAIL: when there are RDS instances with EnableCloudwatchLogsExports property is not present +# e) SKIP: when metadata includes the suppression for rule RDS_INSTANCE_LOGGING_ENABLED + +# +# Select all RDS instance resources from incoming template (payload) +# + +let aws_rds_instances_logging_enabled = Resources.*[ Type == 'AWS::RDS::DBInstance' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "RDS_INSTANCE_LOGGING_ENABLED" +] + + +rule RDS_INSTANCE_LOGGING_ENABLED when %aws_rds_instances_logging_enabled !empty { + %aws_rds_instances_logging_enabled.Properties.EnableCloudwatchLogsExports EXISTS + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: Enable CloudWatch Logs Exports for monitoring and logging. + Fix: Provide EnableCloudWatchLogsExports object to start exporting cloudwatch logs. + >> +} + + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# RDS_STORAGE_ENCRYPTED +# +# Description: +# Checks whether storage encryption is enabled for your RDS DB instances. +# +# +# Reports on: +# AWS::RDS::DBInstance +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no RDS instances present +# b) PASS: when all RDS instances have StorageEncrypted set to true +# c) FAIL: when all RDS instances have StorageEncrypted set to false +# d) FAIL: when there are RDS instances with StorageEncrypted property is not present +# e) SKIP: when metadata includes the suppression for rule RDS_STORAGE_ENCRYPTED + +# +# Select all RDS instance resources from incoming template (payload) +# +let aws_rds_instances_storage_encrypted = Resources.*[ Type == 'AWS::RDS::DBInstance' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "RDS_STORAGE_ENCRYPTED" +] + + +rule RDS_STORAGE_ENCRYPTED when %aws_rds_instances_storage_encrypted !empty { + %aws_rds_instances_storage_encrypted.Properties.StorageEncrypted EXISTS + %aws_rds_instances_storage_encrypted.Properties.StorageEncrypted == true + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: All RDS instances must have encrypted storage. + Fix: Set the StorageEncrypted parameter to true. + >> +} + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# RDS_INSTANCE_DELETION_PROTECTION_ENABLED +# +# Description: +# Checks if an Amazon Relational Database Service (Amazon RDS) instance has deletion protection enabled. +# +# Reports on: +# AWS::RDS::DBInstance +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no RDS instances present +# b) PASS: when all RDS instances have DeletionProtection set to true +# c) FAIL: when all RDS instances have DeletionProtection set to false +# d) FAIL: when there are RDS instances with DeletionProtection property is not present +# e) SKIP: when metadata includes the suppression for rule RDS_INSTANCE_DELETION_PROTECTION_ENABLED + +# +# Select all RDS instance resources from incoming template (payload) +# +let aws_rds_instances_deletion_protection_enabled = Resources.*[ Type == 'AWS::RDS::DBInstance' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "RDS_INSTANCE_DELETION_PROTECTION_ENABLED" +] + +rule RDS_INSTANCE_DELETION_PROTECTION_ENABLED when %aws_rds_instances_deletion_protection_enabled !empty { + %aws_rds_instances_deletion_protection_enabled.Properties.DeletionProtection EXISTS + %aws_rds_instances_deletion_protection_enabled.Properties.DeletionProtection == true + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: All RDS instances must deletion protection enabled. + Fix: Set the parameter for DeletionProtection to true. + >> +} + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# RDS_SNAPSHOT_ENCRYPTED +# +# Description: +# Checks whether Amazon Relational Database Service (Amazon RDS) DB snapshots are encrypted. +# +# +# Reports on: +# AWS::RDS::DBInstance +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no RDS instances present +# b) PASS: when all RDS instances have StorageEncrypted set to true +# c) FAIL: when all RDS instances have StorageEncrypted set to false +# d) FAIL: when there are RDS instances with StorageEncrypted property is not present +# e) SKIP: when metadata includes the suppression for rule RDS_SNAPSHOT_ENCRYPTED + +# +# Select all RDS instance resources from incoming template (payload) +# +let aws_rds_instances_snapshot_encrypted = Resources.*[ Type == 'AWS::RDS::DBInstance' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "RDS_SNAPSHOT_ENCRYPTED" +] + + +rule RDS_SNAPSHOT_ENCRYPTED when %aws_rds_instances_snapshot_encrypted !empty { + %aws_rds_instances_snapshot_encrypted.Properties.StorageEncrypted EXISTS + %aws_rds_instances_snapshot_encrypted.Properties.StorageEncrypted == true + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: All RDS instances must have snapshots encrypted. + Fix: Set the StorageEncrypted parameter to true so by default all snapshots are encrypted. + >> +} + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# AURORA_MYSQL_BACKTRACKING_ENABLED +# +# Description: +# Checks if an Amazon Aurora MySQL cluster has backtracking enabled. +# +# Reports on: +# AWS::RDS::DBCluster +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no RDS instances present +# b) PASS: when all aurora-mysql RDS instances have BacktrackWindow set to greater than 0 +# c) FAIL: when all aurora-mysql RDS instances have BacktrackWindow set to 0 +# d) FAIL: when there are aurora-mysql RDS instances with BacktrackWindow property is not present +# e) SKIP: hen metadata includes the suppression for rule AURORA_MYSQL_BACKTRACKING_ENABLED + +# +# Select all RDS Clusters resources from incoming template (payload) +# + +let aws_rds_clusters_aurora_mysql_backtracking_enabled = Resources.*[ Type == 'AWS::RDS::DBCluster' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "AURORA_MYSQL_BACKTRACKING_ENABLED" +] + +rule AURORA_MYSQL_BACKTRACKING_ENABLED when %aws_rds_clusters_aurora_mysql_backtracking_enabled !empty { + # only eval aurora-mysql engine types + when %aws_rds_clusters_aurora_mysql_backtracking_enabled.Properties.Engine == 'aurora-mysql' { + %aws_rds_clusters_aurora_mysql_backtracking_enabled.Properties.BacktrackWindow EXISTS + %aws_rds_clusters_aurora_mysql_backtracking_enabled.Properties.BacktrackWindow >= 1 + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: All MySQL Aurora RDS DB Clusters have backtrack enabled. + Fix: Set BacktrackWindow parameter value to greater than 0. + >> + } +} + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# DB_INSTANCE_BACKUP_ENABLED +# +# Description: +# Checks if RDS DB instances have backups enabled. +# +# Reports on: +# AWS::RDS::DBInstance +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no RDS instances present +# b) PASS: when all RDS instances have BackupRetentionPeriod set to a positive number +# c) FAIL: when all RDS instances have BackupRetentionPeriod set to 0 +# d) FAIL: when there are RDS instances with BackupRetentionPeriod property is not present +# e) SKIP: when metadata includes the suppression for rule DB_INSTANCE_BACKUP_ENABLED + +# +# Select all RDS instance resources from incoming template (payload) +# + +let aws_rds_instances_db_instance_backup_enabled = Resources.*[ Type == 'AWS::RDS::DBInstance' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "DB_INSTANCE_BACKUP_ENABLED" +] + + +rule DB_INSTANCE_BACKUP_ENABLED when %aws_rds_instances_db_instance_backup_enabled !empty { + %aws_rds_instances_db_instance_backup_enabled.Properties.BackupRetentionPeriod EXISTS + %aws_rds_instances_db_instance_backup_enabled.Properties.BackupRetentionPeriod >= 1 + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: All RDS instances must have automated backup enabled. + Fix: Set the BackupRetentionPeriod to values of 1 to 35 to enable backups. + >> +} + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# RDS_MULTI_AZ_SUPPORT +# +# Description: +# In a Multi-AZ deployment, Amazon RDS automatically provisions and maintains a synchronous +# standby replica in a different Availability Zone. +# +# Reports on: +# AWS::RDS::DBInstance +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there are no RDS instances present +# b) PASS: when all RDS instances have MultiAZ set to true +# c) FAIL: when all RDS instances have MultiAZ set to false +# d) FAIL: when there are RDS instances with MultiAZ property is not present +# e) SKIP: when metadata includes the suppression for rule RDS_MULTI_AZ_SUPPORT + +# +# Select all RDS instance resources from incoming template (payload) +# +let aws_rds_instances_multi_az_support = Resources.*[ Type == 'AWS::RDS::DBInstance' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "RDS_MULTI_AZ_SUPPORT" +] + +rule RDS_MULTI_AZ_SUPPORT when %aws_rds_instances_multi_az_support !empty { + %aws_rds_instances_multi_az_support.Properties.MultiAZ EXISTS + %aws_rds_instances_multi_az_support.Properties.MultiAZ == true + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: All RDS instances must have MultiAZ support enabled. + Fix: Set the MultiAZ parameter to true. + >> +} + +## Config Rule Name : elastic-beanstalk-managed-updates-enabled +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/elastic-beanstalk-managed-updates-enabled.html" + +## Config Rule Name : beanstalk-enhanced-health-reporting-enabled +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/beanstalk-enhanced-health-reporting-enabled.html" + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# ELASTICSEARCH_NODE_TO_NODE_ENCRYPTION_CHECK +# +# Description: +# Elasticsearch domains must enforce Node-to-Node Encryption +# +# Reports on: +# AWS::Elasticsearch::Domain +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there is no elasticsearch domain present +# b) FAIL: when elasticsearch domain has Node-to-Node encryption set to false +# c) PASS: when elasticsearch domain has Node-to-Node encryption set to true +# d) FAIL: when elasticsearch domain has Node-to-Node encryption property missing +# e) SKIP: when metada has rule suppression for ELASTICSEARCH_NODE_TO_NODE_ENCRYPTION_CHECK + +# +# Select all elasticsearch domains from incoming template +# + +let elasticsearch_domains_node2node_encrpytion = Resources.*[ Type == 'AWS::Elasticsearch::Domain' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "ELASTICSEARCH_NODE_TO_NODE_ENCRYPTION_CHECK" +] + +rule ELASTICSEARCH_NODE_TO_NODE_ENCRYPTION_CHECK when %elasticsearch_domains_node2node_encrpytion !empty { + %elasticsearch_domains_node2node_encrpytion.Properties.NodeToNodeEncryptionOptions.Enabled == true + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: Elasticsearch domains must enforce Node-to-Node Encryption. + Fix: Set the NodeToNodeEncryptionOptions.Enabled parameter to true. + >> +} + +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# ELASTICSEARCH_LOGS_TO_CLOUDWATCH +# +# Description: +# Checks if Amazon OpenSearch Service (OpenSearch Service) domains are +# configured to send logs to Amazon CloudWatch Logs. +# +# Reports on: +# AWS::Elasticsearch::Domain +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there is no elasticsearch domain present +# b) FAIL: when elasticsearch domain does not have LogPublishingOptions or Enabled parameter is set to false for all available keys +# c) PASS: when elasticsearch domain has LogPublishingOptions with Enabled parameter is set to true on one key +# d) SKIP: when metada has rule suppression for ELASTICSEARCH_LOGS_TO_CLOUDWATCH + +# +# Select all elasticsearch domains from incoming template +# + +let elasticsearch_domains_logs_cloudwatch = Resources.*[ Type == 'AWS::Elasticsearch::Domain' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "ELASTICSEARCH_LOGS_TO_CLOUDWATCH" +] + +rule ELASTICSEARCH_LOGS_TO_CLOUDWATCH when %elasticsearch_domains_logs_cloudwatch !empty { + + %elasticsearch_domains_logs_cloudwatch.Properties.LogPublishingOptions EXISTS + %elasticsearch_domains_logs_cloudwatch.Properties.LogPublishingOptions.ES_APPLICATION_LOGS.Enabled == true OR + %elasticsearch_domains_logs_cloudwatch.Properties.LogPublishingOptions.SEARCH_SLOW_LOGS.Enabled == true OR + %elasticsearch_domains_logs_cloudwatch.Properties.LogPublishingOptions.INDEX_SLOW_LOGS.Enabled == true + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: Elasticsearch domain must have logging configured to send logs to CloudWatch Logs. + Fix: Set a LogPublishingOptions object to have the property "Enabled" parameter set to true for keys "ES_APPLICATION_LOGS", "SEARCH_SLOW_LOGS", or "INDEX_SLOW_LOGS". + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# ELASTICSEARCH_IN_VPC_ONLY +# +# Description: +# Elasticsearch domains must be in a VPC +# +# Reports on: +# AWS::Elasticsearch::Domain +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there is no elasticsearch domain present +# b) FAIL: when elasticsearch domain does not have VPCOptions or Endpoint properties +# c) PASS: when elasticsearch domain has VPCOptions or Endpoint properties +# d) SKIP: when metada has rule suppression for ELASTICSEARCH_IN_VPC_ONLY + +# +# Select all elasticsearch domains from incoming template +# +let elasticsearch_domains_vpc_required = Resources.*[ Type == 'AWS::Elasticsearch::Domain' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "ELASTICSEARCH_IN_VPC_ONLY" +] + +rule ELASTICSEARCH_IN_VPC_ONLY when %elasticsearch_domains_vpc_required !empty { + %elasticsearch_domains_vpc_required.Properties.VPCOptions EXISTS + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: Elasticsearch domains must be in a VPC. + Fix: Provide VPCOptions object to enable opensearch to function in a VPC. + >> +} +# +##################################### +## Gherkin ## +##################################### +# Rule Identifier: +# ELASTICSEARCH_ENCRYPTED_AT_REST +# +# Description: +# Elasticsearch domains must enforce server side encryption +# +# Reports on: +# AWS::Elasticsearch::Domain +# +# Evaluates: +# AWS CloudFormation +# +# Rule Parameters: +# NA +# +# Scenarios: +# a) SKIP: when there is no elasticsearch domain present +# b) FAIL: when elasticsearch domain has server side encryption set to false +# c) PASS: when elasticsearch domain has server side encryption set to true +# d) FAIL: when elasticsearch domain has server side encryption property is missing +# e) SKIP: when metada has rule suppression for ELASTICSEARCH_ENCRYPTED_AT_REST + +# +# Select all elasticsearch domains from incoming template +# +let elasticsearch_domains_encrypted = Resources.*[ Type == 'AWS::Elasticsearch::Domain' + Metadata.guard.SuppressedRules not exists or + Metadata.guard.SuppressedRules.* != "ELASTICSEARCH_ENCRYPTED_AT_REST" +] + +rule ELASTICSEARCH_ENCRYPTED_AT_REST when %elasticsearch_domains_encrypted !empty { + %elasticsearch_domains_encrypted.Properties.EncryptionAtRestOptions.Enabled == true + << + Guard Rule Set: guard-rules-registry-all-rules + Controls: all rules in AWS Guard Rules Registry + Violation: Elasticsearch domains must enforce server side encryption. + Fix: Set the EncryptionAtRestOptions.Enabled parameter to true. + >> +} + +## Config Rule Name : secretsmanager-secret-periodic-rotation +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/secretsmanager-secret-periodic-rotation.html" + +## Config Rule Name : secretsmanager-using-cmk +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/secretsmanager-using-cmk.html" + +## Config Rule Name : secretsmanager-scheduled-rotation-success-check +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/secretsmanager-scheduled-rotation-success-check.html" + +## Config Rule Name : secretsmanager-secret-unused +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/secretsmanager-secret-unused.html" + +## Config Rule Name : secretsmanager-rotation-enabled-check +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/secretsmanager-rotation-enabled-check.html" + + ## Config Rule Name : ecs-task-definition-user-for-host-mode-check + ## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/ECS_TASK_DEFINITION_USER_FOR_HOST_MODE_CHECK.html" + + ## Config Rule Name : emr-kerberos-enabled + ## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/EMR_KERBEROS_ENABLED.html" + +## Config Rule Name : emr-master-no-public-ip +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/emr-master-no-public-ip.html" + +## Config Rule Name : elasticache-redis-cluster-automatic-backup-check +## Config Rule URL: https://docs.aws.amazon.com/config/latest/developerguide/elasticache-redis-cluster-automatic-backup-check.html" + diff --git a/packages/aws-cloudformation/templates/honeypot.yaml b/packages/aws-cloudformation/templates/honeypot.yaml index 5525aa0..4d8bf3d 100644 --- a/packages/aws-cloudformation/templates/honeypot.yaml +++ b/packages/aws-cloudformation/templates/honeypot.yaml @@ -22,14 +22,45 @@ Parameters: Type: String Default: "" + KmsKeyArnForLogGroup: + Description: The ARN of a KMS key to encrypt the logs instead of using CloudWatch's default encryption (only applies if the stack creates a new log group) + Type: String + Default: "" + LogRetentionInDays: Description: The number of days to retain logs emitted by the honeypot service (only applies if the stack creates a new log group) Type: Number Default: 7 + AllowedValues: + [ + 1, + 3, + 5, + 7, + 14, + 30, + 60, + 90, + 120, + 150, + 180, + 365, + 400, + 545, + 731, + 1096, + 1827, + 2192, + 2557, + 2922, + 3288, + 3653, + ] Conditions: CreateNewCluster: !Equals [!Ref ClusterNameOrArn, ""] CreateNewLogGroup: !Equals [!Ref LogGroupName, ""] + KmsKeyForNewLogGroupSpecified: !Not [!Equals [!Ref KmsKeyArnForLogGroup, ""]] Resources: # ECS @@ -119,8 +150,16 @@ Resources: LogGroup: Type: AWS::Logs::LogGroup + Metadata: + guard: + SuppressedRules: + - CW_LOGGROUP_RETENTION_PERIOD_CHECK # Static analysis is expecting RetentionInDays to be a hard-coded number (one of the specifically allowed values) Condition: CreateNewLogGroup Properties: + KmsKeyId: !If + - KmsKeyForNewLogGroupSpecified + - !Ref KmsKeyArnForLogGroup + - !Ref "AWS::NoValue" RetentionInDays: !Ref LogRetentionInDays Tags: - Key: cloud-native-honeypot @@ -137,35 +176,40 @@ Resources: Service: ecs-tasks.amazonaws.com Action: - sts:AssumeRole - Description: Allows cloud-native-honeypot task to write to CloudWatch Logs - Policies: - - PolicyName: logs-access - PolicyDocument: - Version: "2012-10-17" - Statement: - - Effect: Allow - Action: - - logs:CreateLogStream # Calls on both the log group and log stream as resources, hence both resources being present together - - logs:PutLogEvents - Resource: - - !Sub - - arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:${NameOfChosenLogGroup} - - NameOfChosenLogGroup: - Fn::If: - - CreateNewLogGroup - - !Ref LogGroup - - !Ref LogGroupName - - !Sub - - arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:${NameOfChosenLogGroup}:log-stream:* - - NameOfChosenLogGroup: - Fn::If: - - CreateNewLogGroup - - !Ref LogGroup - - !Ref LogGroupName + Description: Allows cloud-native-honeypot task(s) to write to CloudWatch Logs + ManagedPolicyArns: + - !Ref TaskExecutionRolePolicy Tags: - Key: cloud-native-honeypot Value: true + TaskExecutionRolePolicy: + Type: AWS::IAM::ManagedPolicy + Properties: + Description: Allows cloud-native-honeypot task(s) to write to CloudWatch Logs + PolicyDocument: + Version: "2012-10-17" + Statement: + - Effect: Allow + Action: + - logs:CreateLogStream # Calls on both the log group and log stream as resources, hence both resources being present together + - logs:PutLogEvents + Resource: + - !Sub + - arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:${NameOfChosenLogGroup} + - NameOfChosenLogGroup: + Fn::If: + - CreateNewLogGroup + - !Ref LogGroup + - !Ref LogGroupName + - !Sub + - arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:${NameOfChosenLogGroup}:log-stream:* + - NameOfChosenLogGroup: + Fn::If: + - CreateNewLogGroup + - !Ref LogGroup + - !Ref LogGroupName + TaskRole: Type: AWS::IAM::Role Properties: @@ -177,21 +221,26 @@ Resources: Service: ecs-tasks.amazonaws.com Action: - sts:AssumeRole - Description: Allows cloud-native-honeypot task to publish events to EventBridge - Policies: - - PolicyName: events-access - PolicyDocument: - Version: "2012-10-17" - Statement: - - Effect: Allow - Action: - - events:PutEvents - Resource: - - !GetAtt EventBus.Arn + Description: Allows cloud-native-honeypot task(s) to publish events to EventBridge + ManagedPolicyArns: + - !Ref TaskRolePolicy Tags: - Key: cloud-native-honeypot Value: true + TaskRolePolicy: + Type: AWS::IAM::ManagedPolicy + Properties: + Description: Allows cloud-native-honeypot task(s) to publish events to EventBridge + PolicyDocument: + Version: "2012-10-17" + Statement: + - Effect: Allow + Action: + - events:PutEvents + Resource: + - !GetAtt EventBus.Arn + # EventBridge EventBus: diff --git a/packages/aws-cloudformation/version.json b/packages/aws-cloudformation/version.json index 008971a..6455fc9 100644 --- a/packages/aws-cloudformation/version.json +++ b/packages/aws-cloudformation/version.json @@ -1,3 +1,3 @@ { - "version": "0.1.1" + "version": "0.2.0" } \ No newline at end of file