Strategy - Centralize all AWS KMS Keys  in one account and encrypt EBS volumes in another account
Tags: awscrossaccountcmk, awscrossaccountencryption
Published: 2020-08-26 08:28:19


**Strategy: Centralize AWS KMS CMK in one account**

In the context of Information Security, it is important to maintain the Principle of Least Privilege. One such way you can achieve this for AWS KMS(Key Management Service) is to maintain one centralized account for all your Customer Master Keys (CMKs) and key administrators will grant the necessary encryption/decryption permissions to the key users in another account. This is analogous to the enterprise setting where you have HSM devices to control store all the encryption keys and access to the HSM devices is only allowed to certain HSM administrators. The main benefits of this strategy are:

* AWS Account hosting all KMS Keys will only be used by limited number of people and is easier to maintain/monitor/notify the actions carried out in the account through cloudtrail and cloudwatch logs. 

* Permissions boundary and Service Control Policies (SCP's) are relatively simple in comparison to an AWS account hosting multiple services like EC2, EKS and so on where you will end up creating complicated SCP's and Permissions Boundaries and IAM Identity/Resource policies to ensure only the necessary people have the KMS access. 



**Implementation: Encrypt EBS volume in Account B (111122223333) from a AWS KMS CMK in Account A (444455556666)**

On a high level, there are 3 steps to it:

1. Update the key policy for the CMK in Account A to share it with the desired AWS Account B
2. (Optional) Create a grant if you are going to use Autoscaling group in Account B to make use of KMS CMK in Account A to launch new instances
3. Create the EBS volume in the Account B OR Launch the instance from Autoscaling group


**1. Update the Key Policy for the CMK in Account A**
First, add the following two policy statements to the CMK's key policy in account A, replacing the example ARN with the ARN of the external account (Account B) which will use the KMS Keys. Please note 111122223333 is the Account ID for Account B so you will have to replace it with your account B ID. These 2 policy statements will ensure that Account B have key usage permissions only. 

```
{
   "Sid": "Allow external account 111122223333 use of the CMK",
   "Effect": "Allow",
   "Principal": {
       "AWS": [
           "arn:aws:iam::111122223333:root"
       ]
   },
   "Action": [
       "kms:Encrypt",
       "kms:Decrypt",
       "kms:ReEncrypt*",
       "kms:GenerateDataKey*",
       "kms:DescribeKey"
   ],
   "Resource": "*"
}


{
   "Sid": "Allow attachment of persistent resources in external account 111122223333",
   "Effect": "Allow",
   "Principal": {
       "AWS": [
           "arn:aws:iam::111122223333:root"
       ]
   },
   "Action": [
       "kms:CreateGrant"
   ],
   "Resource": "*"
}
```
**2. (Optional) Create a grant for Autoscaling group**
With grants you can programmatically delegate the use of KMS customer master keys (CMKs) to other AWS principals. Please click on [Grants](https://docs.aws.amazon.com/kms/latest/developerguide/grants.html) to read more about it. In order to achieve this, we will create a grant for the Service Linked Role for Autoscaling groups which if you have not customized will be "AWSServiceRoleForAutoScaling" existing in Account B and this service linked role is created automatically when you create any autoscaling group for the first time.

The following example creates a grant to the AWS KMS CMK with the EC2 Auto Scaling service-linked role as the grantee principal. The create-grant command is run with any IAM  user or role configured in account B (111122223333)

```
aws kms create-grant \
--region us-west-2 \
--key-id arn:aws:kms:us-west-2:444455556666:key/1a2b3c4d-5e6f-1a2b-3c4d-5e6f1a2b3c4d \
--grantee-principal arn:aws:iam::111122223333:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling_CMK \
--operations "Encrypt" "Decrypt" "ReEncryptFrom" "ReEncryptTo" "GenerateDataKey" "GenerateDataKeyWithoutPlaintext" "DescribeKey" "CreateGrant"`
```

**3. Create an EBS volume or launch a new instance from Autoscaling group in Account B**

* To create an EBS volume - Refer to the documentation in AWS to [create a volume](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-creating-volume.html#ebs-create-empty-volume)

* To launch an instance using Autoscaling group - Refer to the documentation for making use of launch configuration to [launch a new instance from Autoscaling group](https://docs.aws.amazon.com/autoscaling/ec2/userguide/create-asg.html)

**Conclusion**
In the end, I also like to mention that the above steps are not restricted to Autoscaling group only but you can create grants for any roles that you want to use for automating the infrastructure provisioning via code. Once the necessary role has the grant, you will be able to create volumes, or launch instances with encrypted volumes until you terminate the grant.