> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# S3 encrypted with cmks remediation

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        To remediate the misconfiguration of S3 Buckets not being encrypted with Customer-Provided CMKs in AWS, follow these step-by-step instructions:

        1. Log in to the AWS Management Console.
        2. Go to the S3 service.
        3. Select the bucket that needs to be encrypted with a Customer-Provided CMK.
        4. Click on the "Properties" tab.
        5. Scroll down to the "Default encryption" section and click on "Edit".
        6. Select "AWS-KMS" as the encryption type.
        7. Choose "Customer managed CMK" for the master key.
        8. Select the CMK that you want to use for encryption from the drop-down menu.
        9. Click on "Save changes".

        Once you have completed these steps, all objects in the selected S3 bucket will be encrypted with the Customer-Provided CMK that you have chosen. It is important to note that you will need to ensure that the appropriate IAM policies are in place to allow access to the CMK for the appropriate users or roles.

        #
      </Accordion>

      <Accordion title="Using CLI">
        To remediate S3 Buckets not being encrypted with Customer-Provided CMKs in AWS using AWS CLI, follow these steps:

        1. Open the AWS CLI on your computer.

        2. Identify the S3 bucket that needs to be remediated.

        3. Check if the S3 bucket is encrypted with a Customer-Provided CMK by running the following command:

           ```
           aws s3api get-bucket-encryption --bucket <bucket-name>
           ```

        4. If the output of the above command shows that the S3 bucket is not encrypted with a Customer-Provided CMK, proceed with the following steps.

        5. Create a Customer-Provided CMK in AWS Key Management Service (KMS) by running the following command:

           ```
           aws kms create-key --description "Customer-Provided CMK for S3 Bucket Encryption"
           ```

        6. Take note of the `KeyId` value returned by the above command, as it will be used in the next step.

        7. Create a new bucket policy for the S3 bucket by running the following command:

           ```
           aws s3api put-bucket-policy --bucket <bucket-name> --policy '{
             "Version": "2012-10-17",
             "Id": "PutEncryptedBucketPolicy",
             "Statement": [
               {
                 "Sid": "DenyUnEncryptedObjectUploads",
                 "Effect": "Deny",
                 "Principal": "*",
                 "Action": "s3:PutObject",
                 "Resource": "arn:aws:s3:::<bucket-name>/*",
                 "Condition": {
                   "StringNotEquals": {
                     "s3:x-amz-server-side-encryption": "aws:kms"
                   }
                 }
               },
               {
                 "Sid": "RequireCustomerProvidedCMK",
                 "Effect": "Deny",
                 "Principal": "*",
                 "Action": "s3:PutObject",
                 "Resource": "arn:aws:s3:::<bucket-name>/*",
                 "Condition": {
                   "Null": {
                     "s3:x-amz-server-side-encryption-aws-kms-key-id": "true"
                   }
                 }
               },
               {
                 "Sid": "AllowEncryptedObjectUploads",
                 "Effect": "Allow",
                 "Principal": "*",
                 "Action": "s3:PutObject",
                 "Resource": "arn:aws:s3:::<bucket-name>/*",
                 "Condition": {
                   "StringEquals": {
                     "s3:x-amz-server-side-encryption": "aws:kms"
                   },
                   "StringEquals": {
                     "s3:x-amz-server-side-encryption-aws-kms-key-id": "<KeyId>"
                   }
                 }
               }
             ]
           }'
           ```

           Replace `<bucket-name>` with the name of the S3 bucket and `<KeyId>` with the `KeyId` value obtained in step 6.

        8. Verify that the S3 bucket is now encrypted with the Customer-Provided CMK by running the following command:

           ```
           aws s3api get-bucket-encryption --bucket <bucket-name>
           ```

           The output of the above command should show that the S3 bucket is now encrypted with the Customer-Provided CMK.

        9. Repeat the above steps for any other S3 buckets that need to be remediated.
      </Accordion>

      <Accordion title="Using Python">
        To remediate the S3 Buckets should be encrypted with customer-provided CMKs misconfiguration in AWS using Python, follow these steps:

        1. Identify the S3 buckets that are not encrypted with customer-provided CMKs. You can use the following Python code to list all the S3 buckets in your AWS account:

        ```
        import boto3

        s3 = boto3.client('s3')

        response = s3.list_buckets()

        for bucket in response['Buckets']:
            print(bucket['Name'])
        ```

        2. For each S3 bucket that is not encrypted with customer-provided CMKs, enable default encryption with a customer-provided CMK. You can use the following Python code to enable default encryption for an S3 bucket:

        ```
        import boto3

        s3 = boto3.client('s3')

        bucket_name = 'your-bucket-name'
        kms_key_id = 'your-kms-key-id'

        s3.put_bucket_encryption(
            Bucket=bucket_name,
            ServerSideEncryptionConfiguration={
                'Rules': [
                    {
                        'ApplyServerSideEncryptionByDefault': {
                            'SSEAlgorithm': 'aws:kms',
                            'KMSMasterKeyID': kms_key_id
                        }
                    }
                ]
            }
        )
        ```

        Replace `your-bucket-name` with the name of the S3 bucket and `your-kms-key-id` with the ID of the customer-provided CMK.

        3. Verify that the S3 bucket is now encrypted with the customer-provided CMK. You can use the following Python code to check the encryption status of an S3 bucket:

        ```
        import boto3

        s3 = boto3.client('s3')

        bucket_name = 'your-bucket-name'

        response = s3.get_bucket_encryption(
            Bucket=bucket_name
        )

        print(response)
        ```

        This will print the encryption configuration for the S3 bucket, including the customer-provided CMK ID.

        Repeat these steps for all the S3 buckets that are not encrypted with customer-provided CMKs.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        # Customer-managed KMS key for the S3 bucket.
        # Replace KEY_ALIAS_NAME and KEY_DESCRIPTION with your values.
        resource "aws_kms_key" "s3_bucket_cmk" {
          description             = "KEY_DESCRIPTION_FOR_S3_BUCKET"
          enable_key_rotation     = true
          deletion_window_in_days = 30
        }

        resource "aws_kms_alias" "s3_bucket_cmk_alias" {
          name          = "alias/KEY_ALIAS_NAME"
          target_key_id = aws_kms_key.s3_bucket_cmk.key_id
        }

        # Existing S3 bucket that must use SSE-KMS with a customer-managed CMK.
        # Replace BUCKET_NAME with your bucket name.
        resource "aws_s3_bucket" "this" {
          bucket = "BUCKET_NAME"
        }

        # Default encryption configuration using the customer-managed CMK.
        # This matches the CLI:
        #   SSEAlgorithm = "aws:kms"
        #   KMSMasterKeyID = YOUR_KMS_KEY_ARN_HERE
        #   BucketKeyEnabled = true
        resource "aws_s3_bucket_server_side_encryption_configuration" "this" {
          bucket = aws_s3_bucket.this.id

          rule {
            apply_server_side_encryption_by_default {
              sse_algorithm     = "aws:kms"
              kms_master_key_id = aws_kms_key.s3_bucket_cmk.arn
            }

            bucket_key_enabled = true
          }
        }
        ```

        This change does not force replacement of the S3 bucket; it updates the default encryption configuration in place. Ensure the KMS key policy allows S3 and required principals to use the key.

        For verification, `terraform plan` should show creation of `aws_kms_key`/`aws_kms_alias` (if new) and an `aws_s3_bucket_server_side_encryption_configuration` with `sse_algorithm = "aws:kms"`, `kms_master_key_id` set to the CMK ARN, and `bucket_key_enabled = true`.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
