Open menu
-->

Use AWS KMS Customer Master Keys for RDS encryption

Cloud Conformity allows you to automate the auditing process of this resolution page. Register for a 14 day evaluation and check your compliance level for free!

Start a Free Trial Product features
Security

Risk level: High (not acceptable risk)

Ensure that your RDS database instances are using KMS CMK customer-managed keys rather than AWS managed-keys (default keys used by RDS when there are no customer keys available), in order to have more granular control over your data-at-rest encryption/decryption process.

This rule resolution is part of the Cloud Conformity Security Package

When you create and use your own KMS CMK customer-managed keys to protect RDS database instances, you gain full control over who can use the keys and access the data encrypted on these instances (including any automated backups, Read Replicas and snapshots created from the instances). The AWS KMS service allows you to create, rotate, disable, enable, and audit CMK encryption keys for RDS. Note: RDS encryption with AWS KMS customer-managed keys is not available for all database instance types. The instance types that are currently supporting encryption are: db.t2.large, db.m3.medium to db.m3.2xlarge, db.m4.large to db.m4.10xlarge, db.r3.large to db.r3.8xlarge and db.cr1.8xlarge.

Audit

To determine if your RDS database instances are encrypted with CMK customer-managed keys, perform the following:

Using AWS Console

01 Login to the AWS Management Console.

02 Navigate to RDS dashboard at https://console.aws.amazon.com/rds/.

03 In the navigation panel, under RDS Dashboard, click Instances.

04 Select the RDS instance that you want to examine.

05 Click Instance Actions button from the dashboard top menu and select See Details.

06 Under Encryption Details section, check the instance Encryption Enabled status:

  1. If the current status is set to No: If the current status is set to No, data-at-rest encryption is not enabled for the selected RDS database instance.
  2. If the current status is set to Yes and the KMS key alias is aws/rds (AWS reserved name): If the current status is set to Yes and the KMS key alias is aws/rds, the selected instance is encrypted using the AWS default key instead of your own KMS CMK key (recommended).

07 Repeat steps no. 4 – 6 for each RDS instance provisioned in the current region. Change the AWS region from the navigation bar to repeat the process for other regions.

Using AWS CLI

01 Run describe-db-instances command (OSX/Linux/UNIX) to list all RDS database names, available in the selected AWS region:

aws rds describe-db-instances
	--region us-east-1
	--query 'DBInstances[*].DBInstanceIdentifier'

02 The command output should return each RDS database instance identifier (name):

[
    "mysql-prod-db"
]

03 Run again describe-db-instances command (OSX/Linux/UNIX) using the specified instance identifier, to determine if the selected database instance is encrypted or not and which KMS key is currently used (AWS-managed or customer-managed):

aws rds describe-db-instances
	--region us-east-1
	--db-instance-identifier mysql-prod-db

04 The command output should reveal the RDS instance encryption status:

  1. If the StorageEncrypted parameter value is set to false, the encryption is not currently enabled:
    {
        "DBInstances": [
            {
                "PubliclyAccessible": true,
                "MasterUsername": "webappdb",
                "MonitoringInterval": 0,
                "LicenseModel": "general-public-license",
    
                ...
    
                "CACertificateIdentifier": "rds-ca-2015",
                "StorageEncrypted": false,
                "DBInstanceClass": "db.m3.medium",
                "DbInstancePort": 0,
                "DBInstanceIdentifier": "mysql-prod-db"
            }
        ]
    }
    
  2. If the StorageEncrypted parameter value is set to true, the instance encryption is enabled and the KMS key ARN (Amazon Resource Name) used for the encryption/decryption process is available as value for KmsKeyId parameter (highlighted):
    {
        "DBInstances": [
            {
                "PubliclyAccessible": true,
                "MasterUsername": "webappdb",
                "MonitoringInterval": 0,
                "LicenseModel": "general-public-license",
    
                ...
    
                "CACertificateIdentifier": "rds-ca-2015",
                "KmsKeyId": "arn:aws:kms:us-east-1:123456789012:
                             key/8d8d3ab9-db2a-428f-b82e-d38cb05ce1a4",
                "StorageEncrypted": true,
                "DBInstanceClass": "db.m3.medium",
                "DbInstancePort": 0,
                "DBInstanceIdentifier": "mysql-prod-db"
    	     }
        ]
    }
    

05 Now run list-aliases command (OSX/Linux/UNIX) to list all the KMS keys aliases (names) and their ARNs, available in specified region:

aws kms list-aliases
	--region us-east-1

06 The command output should return each available KMS key alias, ID and ARN. Now compare each key ID (TargetKeyId parameter value - highlighted) with the KmsKeyId parameter ID value returned at the previous step in order to determine the KMS key type used for the instance encryption. If the AliasName parameter value for the matched ID is alias/aws/rds, the selected instance is encrypted using the AWS default key instead of a KMS customer-managed key (recommended).

{
    "Aliases": [
       {
           "AliasArn": "arn:aws:kms:us-east-1:123456789012:alias/aws/ebs",
           "AliasName": "alias/aws/ebs",
           "TargetKeyId": "d6c03026-b0bd-451e-a864-a68355f4f035"
       },
       {
           "AliasArn": "arn:aws:kms:us-east-1:123456789012:alias/aws/rds",
           "AliasName": "alias/aws/rds",
           "TargetKeyId": "8d8d3ab9-db2a-428f-b82e-d38cb05ce1a4"
       }
    ]
}

07 Repeat steps no. 1 – 6 for each RDS instance provisioned in the current region. Change the AWS region by using the --region filter to repeat the process for other regions.

Remediation / Resolution

Since RDS encryption is an immutable setting that must be turned on at the creation time, to migrate a database from unencrypted to encrypted, the database must be backed up and restored onto a new one with the encryption flag enabled. To use your own KMS CMK customer-managed key to encrypt an existing RDS instance, perform the following:

Using AWS Console

01 Login to the AWS Management Console.

02 Navigate to IAM dashboard at https://console.aws.amazon.com/iam/.

03 In the left navigation panel, click Encryption Keys.

04 Select the appropriate AWS region from the Filter menu:

Select the appropriate AWS region from the Filter menu

(must match the region where the AWS resource that will use the key was created).

05 Click Create Key button from the top menu.

06 Enter an alias (name) and a description for the new CMK, then click Next Step.

07 Under Key Administrators section, select which IAM users and/or roles can administer the CMK, then click Next Step.

08 Under This Account section, select which IAM users and/or roles can use the CMK to encrypt/decrypt data with the AWS KMS API.

09 (Optional) Under External Accounts section, click Add an External Account and enter an external account ID in order to add another AWS account that can use this CMK to encrypt/decrypt data. The owners of the external AWS accounts must also provide access to this CMK by creating policies for their IAM users.

10 Click Next Step.

11 Under Preview Key Policy section, click Finish to create your new CMK. Once the key is created, the KMS dashboard will display a confirmation message: “Your master key was created successfully. Alias: <the CMK display name>”.

12 Click on the newly created CMK alias and copy the key full ARN (Amazon Resource Name) displayed in the Summary section:

ARN (Amazon Resource Name) displayed in the Summary section

13 Now the new CMK must be applied to encrypt/decrypt the RDS instance data. In order to start the process, navigate to the RDS dashboard at https://console.aws.amazon.com/rds/.

14 In the navigation panel, under RDS Dashboard, click Instances.

15 Select the RDS database instance that you want to encrypt.

16 Click Instance Actions button from the dashboard top menu and select Take Snapshot.

17 On the Take DB Snapshot page, enter a name for the instance snapshot in the Snapshot Name field and click Take Snapshot (the backup process may take few minutes and depends on your instance storage size).

18 Select the new created snapshot and click the Copy Snapshot button from the dashboard top menu.

19 On the Make Copy of DB Snapshot page, perform the following:

  1. In the New DB Snapshot Identifier field, enter a name for the new snapshot (copy).
  2. Check Copy Tags so the new snapshot can have the same tags as the source snapshot.
  3. In the Master Key dropdown list, select Enter a key ARN to provide your own CMK ARN.
  4. In the ARN field, paste the CMK ARN copied at step no. 12 (e.g. arn:aws:kms:::key/).

20 Click Copy Snapshot to create an encrypted copy of the selected instance snapshot.

21 Select the new snapshot copy and click Restore Snapshot button from the dashboard top menu. This will restore the encrypted snapshot to a new database instance.

22 On the Restore DB Instance page, enter a unique name for the new database instance in the DB Instance Identifier* field.

23 Review the instance configuration details and click Restore DB Instance.

24 As soon as the new instance provisioning process is completed (the instance status becomes available), you can update your application configuration to refer to the endpoint (e.g. mysql-prod-db-encrypted.cdi32cpelkwh.us-east-1.rds.amazonaws.com) of the new database instance (encrypted with your own CMK). Once the database endpoint is changed at your application level, you can remove the instance encrypted with the AWS KMS default key.

25 Repeat steps no. 13 – 24 for each RDS instance that you want to encrypt with your own KMS key, available in the current region. Repeat steps no. 1 – 12 to create a new KMS key. Change the AWS region from the navigation bar to repeat the process for other regions.

Using AWS CLI

01 Create a policy that enables the selected IAM users and/or roles to administer the new CMK and the selected IAM users and/or roles to encrypt/decrypt data using the KMS API. Create a new policy document called rds-cmk-policy.json and paste the following (replace the highlighted details - the ARNs for the IAM users and/or roles - with your details):

{
  "Version": "2012-10-17",
  "Id": "key-policy-5",
  "Statement": [
    {
      "Sid": "Enable IAM User Permissions",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:root"
      },
      "Action": "kms:*",
      "Resource": "*"
    },
    {
      "Sid": "Allow access for Key Administrators",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:role/EC2Manager"
      },
      "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 use of the key",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:user/EC2Admin"
      },
      "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::123456789012:user/EC2Admin"
      },
      "Action": [
        "kms:CreateGrant",
        "kms:ListGrants",
        "kms:RevokeGrant"
      ],
      "Resource": "*",
      "Condition": {
        "Bool": {
          "kms:GrantIsForAWSResource": "true"
        }
      }
    }
  ]
}

02 Run create-key command (OSX/Linux/UNIX) using the AWS region where the RDS resource is located and the policy name created earlier (rds-cmk-policy.json) to create the new CMK customer-managed key:

aws kms create-key
	--region us-east-1
	--description 'CMK for AWS RDS instance(s) encryption'
	--policy file://rds-cmk-policy.json

03 The command output should return the new KMS CMK metadata. Copy the CMK unique ID (KeyID parameter value) for using it later to specify the CMK required for encryption:

{
    "KeyMetadata": {
        "KeyId": "7c41886d-1f25-4dc9-9897-a9b02c2e3999",
        "Description": "CMK for AWS RDS instance(s) encryption",
        "Enabled": true,
        "KeyUsage": "ENCRYPT_DECRYPT",
        "KeyState": "Enabled",
        "CreationDate": 1460740399.556,
        "Arn": "arn:aws:kms:us-east-1:123456789012:
                key/7c41886d-1f25-4dc9-9897-a9b02c2e3999",
        "AWSAccountId": "123456789012"
    }
}

04 Run create-alias command (OSX/Linux/UNIX) using the newly created key ARN to attach an alias (display name) to the CMK. The alias name must start with the prefix "alias/":

aws kms create-alias
	--alias-name alias/MyRDSDatabaseCMK
	--target-key-id arn:aws:kms:us-east-1:123456789012:key/7c41886d-1f25-4dc9-9897-a9b02c2e3999

05 Run create-db-snapshot command (OSX/Linux/UNIX) to create a snapshot from your existing database instance. The following command example creates a snapshot named mysql-prod-db-snapshot from an RDS database instance named mysql-prod-db:

aws rds create-db-snapshot
	--region us-east-1
	--db-snapshot-identifier mysql-prod-db-snapshot
	--db-instance-identifier mysql-prod-db

06 The command output should return the new snapshot metadata:

{
    "DBSnapshot": {
        "Engine": "mysql",
        "Status": "creating",
        "AvailabilityZone": "us-east-1a",
        "PercentProgress": 0,
        "MasterUsername": "webappdb",
        "Encrypted": false,
        "LicenseModel": "general-public-license",
        "StorageType": "gp2",
        "VpcId": "vpc-f7ac5792",
        "DBSnapshotIdentifier": " mysql-prod-db-snapshot",
        "InstanceCreateTime": "2016-05-03T15:41:246.042Z",
        "OptionGroupName": "default:mysql-5-6",
        "AllocatedStorage": 5,
        "EngineVersion": "5.6.27",
        "SnapshotType": "manual",
        "Port": 3306,
        "DBInstanceIdentifier": "mysql-prod-db"
    }
}

07 Run copy-db-snapshot command (OSX/Linux/UNIX) using the CMK ID (copied at step no. 3) to create an encrypted copy of the database instance snapshot created earlier:

aws rds copy-db-snapshot
	--region us-east-1
	--source-db-snapshot-identifier mysql-prod-db-snapshot
	--target-db-snapshot-identifier mysql-prod-db-snapshot-encrypted
	--copy-tags
	--kms-key-id 7c41886d-1f25-4dc9-9897-a9b02c2e3999

08 The command output should return the encrypted instance snapshot (copy) metadata:

{
    "DBSnapshot": {
        "Engine": "mysql",
        "Status": "creating",
        "AvailabilityZone": "us-east-1a",
        "SourceRegion": "us-east-1",
        "PercentProgress": 0,
        "MasterUsername": "webappdb",
        "Encrypted": true,
        "LicenseModel": "general-public-license",
        "StorageType": "gp2",
        "KmsKeyId": "arn:aws:kms:us-east-1:123456789012:
                     key/7c41886d-1f25-4dc9-9897-a9b02c2e3999",
        "VpcId": "vpc-f7ac5792",
        "SourceDBSnapshotIdentifier": "arn:aws:rds:us-east-1:123456789012:
                                       snapshot:mysql-prod-db-snapshot",
        "DBSnapshotIdentifier": "mysql-prod-db-snapshot-encrypted",
        "InstanceCreateTime": "2016-05-03T15:44:26.042Z",
        "OptionGroupName": "default:mysql-5-6",
        "AllocatedStorage": 5,
        "EngineVersion": "5.6.27",
        "SnapshotType": "manual",
        "Port": 3306,
        "DBInstanceIdentifier": "mysql-prod-db"
    }
}

09 Run restore-db-instance-from-db-snapshot command (OSX/Linux/UNIX) to restore the encrypted snapshot created at the previous step to a new database instance:

aws rds restore-db-instance-from-db-snapshot
	--region us-east-1
	--db-instance-identifier mysql-prod-db-cmk-encrypted
	--db-snapshot-identifier mysql-prod-db-snapshot-encrypted

10 If successful, the command output should return the new encrypted database instance metadata. The CMK customer-managed key used for instance encryption is available as value for the KmsKeyId parameter (highlighted):

{
    "DBInstance": {
        "PubliclyAccessible": true,
        "MasterUsername": "webappdb",
        "MonitoringInterval": 0,
        "LicenseModel": "general-public-license",
        ...
        "DbiResourceId": "db-DOXVANNOGAXV5BMSEF2U2JEW9B",
        "CACertificateIdentifier": "rds-ca-2015",
        "KmsKeyId": "arn:aws:kms:us-east-1:123456789012:
                     key/7c41886d-1f25-4dc9-9897-a9b02c2e3999",
        "StorageEncrypted": true,
        "DBInstanceClass": "db.m3.medium",
        "DbInstancePort": 0,
        "DBInstanceIdentifier": "mysql-prod-db-cmk-encrypted"
    }
}

11 Repeat steps no. 5 – 10 for each RDS instance provisioned in the current region. Repeat steps no. 1 – 4 to create a new KMS key. Change the AWS region by using the --region filter to repeat the process for other regions.

References

Publication date May 4, 2016