Elasticsearch domains should be encrypted with KMS Customer Master Keys

Description

Encrypt your Amazon Elasticsearch domains with KMS Customer Master Keys (CMKs).

Rationale

KMS Custom Master Keys protect your domains and allow more granular control over the encryption/decryption process.

Remediation

From the console

Follow the Enabling Encryption of Data at Rest docs to learn how to encrypt Amazon Elasticsearch domains in the AWS Console.

From the command line

  1. Create a new policy JSON document with the following configuration:

    es-kms-cmk-policy.json

        {
        "Id": "es-custom-key-policy",
        "Statement": [
            {
            "Sid": "Enable IAM User Permissions",
            "Effect": "Allow",
            "Principal": {"AWS": "arn:aws:iam::111122223333:root"},
            "Action": "kms:*",
            "Resource": "*"
            },
            {
            "Sid": "Grant access to CMK manager",
            "Effect": "Allow",
            "Principal": {"AWS": "arn:aws:iam::111122223333:role/AmazonESManager"},
            "Action": [
                "kms:Create*",
                "kms:Describe*",
                "kms:Enable*",
                "kms:List*",
                "kms:Put*",
                "kms:Update*",
                "kms:Revoke*",
                "kms:Disable*",
                "kms:Get*",
                "kms:Delete*",
                "kms:ScheduleKeyDeletion",
                "kms:CancelKeyDeletion"
            ],
            "Resource": "*"
            },
            {
            "Sid": "Allow the use of the CMK",
            "Effect": "Allow",
            "Principal": {"AWS": "arn:aws:iam::111122223333:user/ESAdmin"},
            "Action": [
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:DescribeKey"
            ],
            "Resource": "*"
            },
            {
            "Sid": "Allow attachment of persistent resources",
            "Effect": "Allow",
            "Principal": {"AWS": "arn:aws:iam::111122223333:user/ESAdmin"},
            "Action": [
                "kms:CreateGrant",
                "kms:ListGrants",
                "kms:RevokeGrant"
            ],
            "Resource": "*",
            "Condition": {
                "Bool": {"kms:GrantIsForAWSResource": "true"}
            }
            }
        ]
        }
        
  2. Run create-key to create a KMS key with the new policy document.

    create-key.sh

        aws kms create-key
        --description 'KMS CMK policy for encrypting es domain data'
        --policy file://es-kms-cmk-policy.json
        
  3. Run create-alias with the returned ARN key to attach a new alias to the CMK.

    create-alias.sh

        aws kms create-alias
            --alias-name your-alias/ESCustomCMK
            --target-key-id arn:aws:kms:111122223333:key/abcdabcd-aaaa-bbbb-cccc-abcdabcdabcd
        
  4. Run create-elasticsearch-domain with the returned configuration data in step 3 to create the selected domain with encryption-at-rest-options set as enabled= true and the KmsKeyId=your-key-id.

    create-elasticsearch-domain.sh

        aws es create-elasticsearch-domain
            --domain-name your-domain-name
            ....
            --encryption-at-rest-options Enabled=true,KmsKeyId="abcdabcd-aaaa-bbbb-cccc-abcdabcdabcd"