Search code examples
amazon-web-servicesamazon-s3amazon-iamenforcement

Deny CreateBucket in S3 unless AES256 Encryption Checked


I have been trying for the better part of a day. I am, as an administrator, attempting to require users to check the "Automatically encrypt objects when they are stored in S3" button (AES256) when creating their S3 buckets. I've tried about everything can think of. So far, I have only gotten 2 separate results.

As a test user, I am either allowed to create buckets (with or without checking encryption), or I am denied (with or without checking encryption).

The last effort has resulted in the following policy being applied to the test user, in which case I am denied creating a bucket whether or not I check the encryption box

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Deny",
            "Action": [
                "s3:CreateBucket"
            ],
            "Resource": "*",
            "Condition": {
                "StringNotEquals": {
                    "s3:x-amz-content-sha256": "AES256"
                },
                "Null": {
                    "s3:x-amz-content-sha256": true
                }
            }
     ]

}

I have combined the above policy with S3AllowFullAccess, with other custom policies allowing access, but I simply cannot get it to work.

Any help is appreciated


Solution

  • The CreateBucket() command does not accept a bucket encryption setting.

    For example, when creating a bucket from the AWS CLI, the options are:

    aws s3api  create-bucket
    [--acl <value>]
    --bucket <value>
    [--create-bucket-configuration <value>]
    [--grant-full-control <value>]
    [--grant-read <value>]
    [--grant-read-acp <value>]
    [--grant-write <value>]
    [--grant-write-acp <value>]
    [--object-lock-enabled-for-bucket | --no-object-lock-enabled-for-bucket]
    [--cli-input-json <value>]
    [--generate-cli-skeleton <value>]
    

    It is not possible to specify bucket encryption.

    Instead, bucket encryption is specified with the put-bucket-encryption command:

    aws s3api put-bucket-encryption
    --bucket <value>
    [--content-md5 <value>]
    --server-side-encryption-configuration <value>
    [--cli-input-json <value>]
    [--generate-cli-skeleton <value>]
    

    This means that it is not possible to create a policy on CreateBucket() that forces a server-side encryption value. It needs to be set after the bucket is created.

    You could create an Amazon CloudWatch Events Rule that activates on CreateBucket(), and triggers an AWS Lambda function. You could then code the function to call PutBucketEncryption() on the bucket.

    Update: Rather than setting encryption at the bucket level, you could use a policy that requires objects themselves to be encrypted.

    Here is an Example Service Control Policies from AWS Organizations that requires everybody only upload objects with encryption:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "DenyIncorrectEncryptionHeader",
          "Effect": "Deny",
          "Action": "s3:PutObject",
          "Resource": "*",
          "Condition": {
            "StringNotEquals": {
              "s3:x-amz-server-side-encryption": "AES256"
            }
          }
        },
        {
          "Sid": "DenyUnEncryptedObjectUploads",
          "Effect": "Deny",
          "Action": "s3:PutObject",
          "Resource": "*",
          "Condition": {
            "Null": {
              "s3:x-amz-server-side-encryption": true
            }
          }
        }
      ]
    }