This course looks at how you can use the same Customer Master Keys (CMKs) for encryption across multiple AWS accounts using the Key Management Service. It will define the key principles and components required to share the CMKs in addition to a demonstration on how to carry out those actions.
Learning Objectives
By the end of this course, you will have the knowledge and understanding of how to share your CMKs used within the AWS Key Management Service service across each of your AWS accounts, allowing you to implement encryption using the same keys
Intended Audience
This course has been created for security engineers and architects who are responsible for managing and implementing data encryption methods across AWS accounts.
Prerequisites
To get the most from this course you should be familiar with the Key Management Service and IAM permissions and JSON policies. For more information relating to both AWS IAM and KMS, please see our existing courses here:
Identity & Access Management (IAM)
Hello and welcome to this lecture, focusing on KMS permissions and key policies. Before I begin, I just want to highlight a couple of key components within KMS. Firstly, the Customer Master Key is known as the CMK. The CMK is the main key type within KMS and can generate, encrypt and decrypt data encryption keys known as the DEKs, which are used outside of the KMS service by other AWS services to perform encryption against your data.
CMKs can either be managed by AWS or by you and me as customers of AWS. CMKs managed by AWS are used by other AWS services that have the ability to interact with KMS directly to perform encryption against data. For example, Amazon S3, in particular, SSE-KMS, which is server-side encryption using the Key Management Service. CMKs that are created and generated by you and I rather than AWS provide the ability to implement greater flexibility, such as being able to manage the key including rotation, governing access and key policy configuration, along with being able to both enable and disable the key when it is no longer required.
With many services that you use within AWS, you can control access using identity-based access IAM policies. However, KMS also uses resource-based policies when it comes to CMK access. If you want to allow other IAM users or roles in a different AWS account in which a CMK was created, then you must understand how KMS permissions work. In all cases, to manage access to your CMKs, you must use a key policy. Without a key policy associated to your CMK, users will not be able to use it. Permissions to allow you to access and use a CMK from a different AWS account can't be given and generated using IAM alone. As a result, you have to use and edit a resource-based key policy in the AWS account where the CMK resides, in addition to an IAM identity-based policy in the AWS account that wants to access the CMK. One point to remember is that you can only edit key policies for keys that you have created. So you can't share AWS managed CMKs between accounts.
Key policies are resource-based policies that are tied to your CMK. And the key policy document itself is JSON-based, much like IAM policies. As a result, they typically look like the following.
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "statement identifier",
"Effect": "effect",
"Principal": "principal",
"Action": "action",
"Resource": "resource",
"Condition": {"condition operator": {"condition context key": "context key value"}}
}]
}
During the creation of a CMK, whether you create it programmatically or if you've created it through the AWS Management Console, KMS will create a default key policy for you to allow principles to use the CMK in question. By default, KMS will configure the root user of the AWS account in which the key was created full access to the CMK within the key policy.
When you create a CMK through the Management Console, then you can configure different permissions sets. These include key administrators and users. Key administrators can only administer the CMK, but not use it to perform any encryption functions. Whereas users have the ability to access the CMK to perform encryption of data. The permissions that can be given to use the key for any user selected, are as follows.
kms:Encrypt
kms:Decrypt
kms:ReEncrypt*
kms:GenerateDataKey*
kms:DescribeKey
So the first step in allowing the sharing of your CMK across AWS accounts is to add the principles from the external account into the key policy of the CMK. To do so, you will need to add a statement as shown where the text embed should be replaced with the external AWS account number.
{
"Sid": "Allow another AWS Account to use this CMK",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::123456789012:root"
]
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*"
}
You could create this key policy statement with even more granularity by limiting the specific actions required, or by specifying individual users or roles. For example, instead of using the root of the external account and the principal parameter, you could add an IAM user named Bob.
"Principal": {
"AWS": [
"arn:aws:iam::123456789012:user/Bob"
]
},
Once this statement is added to the key policy, the users within the account would still not be able to use the CMK until IAM permissions in the external account have been added to specific users or roles. And once the key policy has been edited to allow either the external account or specific users or roles from the external account access to a CMK, identity-based policies need to be associated with those users or roles who intend to use the CMK.
Let's assume that in the key policy, we set the principal component of the root of the external account. This would mean I can set the IAM permissions on any user or role in the external account to allow access to the CMK. The permissions required would need to include a statement as shown for the user or role.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Allow the use of a CMK In Account 1234567889012",
"Effect": "Allow",
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "arn:aws:kms:us-east-2:123456789012:key/5e698272-88c6-4f6b-970e-1d1dbd0c6412
"
}
]
}
In this policy, you'll notice that we have an additional parameter of resource, which details which CMK the action should take effect on. And in this instance, is the Amazon resource name of the CMK in which we updated the key policy for. One other point that's important is that if for example, your key policy only allowed the kms:Decrypt
action, but your IAM policy allowed both the kms:Decrypt
and kms:encrypt
actions, then only the kms:Decrypt
action would be allowed, as that is all that is allowed in the key policy, which takes precedence.
Once the policy is associated with the user or role, you will now be able to use the CMK to perform encryption functions. However, please do be aware that even though you have access to the CMK from a different account, the CMK will not be shown in the AWS Management Console for integrated services. Instead, you must use the ARN of the CMK.
I will now perform a demonstration that shows the following steps. I'll show you how to update the key policy of an existing customer-managed CMK allowing access to an external account to use the CMK. I'll show you how to apply the required IAM permissions to a user in the external account to allow them to use the CMK. And then I'll test the access of the CMK across accounts by uploading a file within S3 using the shared CMK.
So I've logged-in to my AWS Management Console of the AWS account, where I have the CMK. So let's go to the KMS service because the first thing we need to do is to edit the key policy of my CMK. Over here we have our AWS managed keys, and also our customer-managed keys. And remember, we can only share customer-managed keys between AWS accounts, we can't share AWS managed keys. So I've got two keys here, one of them is pending deletion at the moment, and we have an active key here. So the demo key is the key that I'm going to use. So to edit the key policy, what we need to do is first select the key, and this brings up all the configuration and details about the CMK. And if we scroll down here, we can see the key policy. And over on the right-hand side, we can switch to the policy view and this will show us the JSON view of the policy itself. So as we scroll down here, we can see different statement IDs, for example, this one will allow access for key administrators. So this will show who the key administrator is, and the actions that they can perform. And further down here, we have another statement, which is, "Allow the use of the key". And this is the statement that we're interested in because what we want to do is, add another principle in here, that points to the root account of the secondary AWS account that we want to allow access.
So let's go ahead and click on this Edit button. And I'm going to scroll down to that statement ID again, and I'm going to add in another principle. So if I just copy and paste this for ease, but I want to change the AWS account that I'm interested in. So let me put in the details of the secondary AWS account and it's going to be the root account. So what this section of the policy is saying, is allowing all the principles listed here, the ability to use this key and perform these KMS actions such as encrypt, decrypt, etc. So let's go now and save those changes.
Okay, so now what we want to do is to swap over to our secondary account where I now need to apply identity-based policies to allow a user or multiple users within that account to have access to this CMK. But before I do that, I need to make a note of the ARN of this key, which is found here at the top because you're gonna need to add this ARN in as the resource within the identity-based policies. So make sure you take a copy of the key's ARN.
Also, as I mentioned earlier in the course, that KMS is regional. So whatever encryption you're going to be performing from the other account, it needs to be in the same region. And as we can see up here, currently, I'm in the Ireland region. So that's just something to remember as well.
Okay, so let me now cross over to the other account. Okay, so now I'm logged-in to my secondary account. So the first thing I need to do, is to go to IAM. And from here, I'm going to select the user that I want to have access to the CMK that I just edited the key policy for. So I'm going to select Stuart, and I'm going to attach an inline policy. So this policy will be directly attached to this identity. So if I go across to Add inline policy, and go to JSON, and to make things a lot easier for this demonstration, I created a policy before, so I'm just going to paste that in. So let me just run through that quickly, it's a very simple policy. So we have the effect of Allow and these are the actions which are the KMS actions, which is effectively the same as what we had in the key policy. But in this policy, we also have the resource parameter. And this is the ARN of the key that we edited the key policy for. So once you've added the policy in, click on Review policy, and then we need to give it a name. I'll just call this Key Demo, and then down to Create policy. Now if we look at the inline policies, we can now see that we have the Key Demo policy attached to this identity.
So let's now go ahead and test this encryption to see if the user Stuart within this account can actually encrypt using the CMK in the primary account. Now as we can see at the top here, we're currently logged in as Stuart, so let's go ahead and try some encryption. Let me just flip over to S3 to try and encrypt using the CMK from the primary account. Now I have a number of buckets here, we can see that I have two buckets here, in the Ireland region. Because remember, the key was created in the Ireland region of the primary account, so I need to make sure that I'm encrypting within the same region. So if I go into this bucket here, and if I upload an object, just add in an image file, just a JPEG. Click on Next, now we have a number of different options here for S3, just gonna leave all those as default for this demonstration. Now the part that I'm interested in is on this property page. So if I scroll down, we have the encryption option here. So I want to use the AWS KMS master-key to encrypt this file. If I select on this box here, I can select a custom KMS ARN so that the key won't actually be listed in this drop down list because it doesn't exist within this account. So we have to use the full ARN of the CMK from the primary account. So if I select the custom KMS ARN, and then paste in the ARN of the key from the primary account. We can see here that this is a different account ID to the current account ID that I'm using showing that this is the key from the primary account. And then I can simply click on Upload. And there we have it, the file is uploaded.
Now if I select this file, we can see here down under encryption, we have server-side encryption enabled, and here we have the KMS ID. And this is the ARN of the key from the primary account. And we know that, because we have the primary account ID here, so that's worked. So just to quickly run through what we've done again, from the primary account where the Customer Master Key existed, we edited the key policy and added the secondary account root user as a user of that key. We then went into the secondary account, and we added an inline policy for a user that we wanted to be able to use that key from the primary account, and we referenced the resource as the ARN of that CMK from the primary account. And then we went into S3 and uploaded an object using a custom KMS ARN, and again, put in the ARN of the primary key. And it's as simple as that.
That brings me to the end of this course which explained how to share a CMK across multiple different accounts through the use of resource-based key policies and identity-based policies. If you'd like additional information on both IAM and the Key Management Service, then please take a look at the resources below.
Overview of AWS Identity & Access Management (IAM): https://cloudacademy.com/course/overview-of-aws-identity-and-access-management-iam/
How to use KMS Key Encryption to Protect your Data: https://cloudacademy.com/course/amazon-web-services-key-management-service-kms/
Feedback on our courses here at Cloud Academy is valuable to both us as trainers and any students looking to take the same course in the future. If you have any feedback, positive or negative, it would be greatly appreciated if you can contact support@cloudacademy.com. Thank you for your time and good luck with your continued learning of cloud computing. Thank you.
Stuart has been working within the IT industry for two decades covering a huge range of topic areas and technologies, from data center and network infrastructure design, to cloud architecture and implementation.
To date, Stuart has created 150+ courses relating to Cloud reaching over 180,000 students, mostly within the AWS category and with a heavy focus on security and compliance.
Stuart is a member of the AWS Community Builders Program for his contributions towards AWS.
He is AWS certified and accredited in addition to being a published author covering topics across the AWS landscape.
In January 2016 Stuart was awarded ‘Expert of the Year Award 2015’ from Experts Exchange for his knowledge share within cloud services to the community.
Stuart enjoys writing about cloud technologies and you will find many of his articles within our blog pages.