Key Management Service (KMS)
KMS is a powerful service and so understanding how to control access is critical, this lecture focuses on how to grant access to specific keys using 3 different methods, these being: Using Key Policies, Key Policies with IAM Policies, Key Policies with Grants. Understanding how each of these methods differ is essential is securing your key infrastructure.
Hello and welcome to this lecture where I will be diving deeper on how to secure access to your KMS keys and associated levels of permission.
With many services that you use within AWS, you can control access using IAM policies whether that is against a user, group, role or even a federated user. The point is access control for most services can be completely controlled and governed by using IAM alone. For KMS however, this is not the case. 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 your CMK can't be given and generated using IAM alone. As a result, there are a number of different ways in which you can control access to your keys in KMS, just by using key policies, using key policies with IAM, and using key policies with grants. Let me run through each of these options starting with key policies.
As I briefly mentioned in the previous lecture, key policies are resource based policies which are tied to your CMK. And if you want a principal to be able to access your CMK, then a key policy must be in place to do so. The key policy document itself is JSON based much like IAM policies are and the document syntax is much like other IAM policies. They contain elements such as resource, action, effect, principal and optionally conditions. As a result, they typically look like the following.
During the creation of a CMK, whether you create it programmatically or if you create it through the AWS Management Console, either way KMS will create a default key policy for you to allow principals to use the CMK in question as remember a key policy is required for all CMKs. Within both of these default key policies, KMS will configure the root of the AWS account full access to the CMK, by doing so ensures that the CMK will never become unusable as it's not possible to delete the root account. If full access of the CMK was given to another user and then that user was deleted from IAM, it would not be possible to manage the CMK unless you contacted AWS support to regain the control required. Also, by allowing the root account full access to the CMK performs another important and useful function. It allows access to be given to the CMK by normal IAM policies for users and roles, etc. That's why it's not possible to allow users access to a CMK without a key policy. Without the root account having full access in the key policy, IAM can't be used to manage access for other users.
Within the key policy, this section would look as follows. The resource section shows an asterisk which essentially means this CMK that the key policy is being applied to. When you create your CMK through the Management Console, then you have the chance to configure different permission sets. These include key administrators of the CMK and users which are allowed access to the CMK.
You'll be asked to firstly define the key administrators. These can either be users or roles that you have setup and configured within IAM. These principals can only administer the CMK and not use it to perform any encryption function that may be needed within the CMK. The administrative actions that are allowed by the key admins are shown on screen. During the selection of key admins, you can also specify if you would like them to be able to delete the key via a checkpoint option. An important point to bear in mind is that although these key administrators do not have access to use the CMK, they do have access to update the associated key policy. As a result, if they wanted to, they could give themselves access to use the CMK.
Next you'll be asked which users you want to allow to use the CMK. And by use, it's essentially asking which users should be allowed to perform any encryption using the CMK. In addition to these permissions, the users associated will also be able to use grants to delegate a subset of their own permissions to another service which integrates with KMS. For example, if you are attaching an encrypted EBS volume to an EC2 instance, then through the use of grants, you as the key user of the CMK which encrypted the EBS volume implicitly give permission to EC2 to be able to attach that encrypted EBS volume. Within the key policy, the grant permissions look as follows. For every user or role selected as a user of the key will be displayed within the principal section. As you can see from this example, the only user currently selected for this key is Cloud Academy. The permissions given to use the key for any user selected are as follows.
As the key policy uses the same syntax as IAM policies, you can also restrict access to the CMK in the same way that you can restrict access to resources via the Effect element. Instead of using the Effect Allow, you can instead restrict and deny a particular user access to a CMK by specifying the Effect as deny. As mentioned, we can also use key policies in conjunction with IAM policies, but only if you have the following entry within the key policy allowing the root full KMS access to the CMK, by doing so enables you to centralize your permissions administration from within IAM as you would likely be doing for many other AWS services. This would mean you can configure your IAM policies to allow users, groups and roles to perform the encryption and decryption process, for example using the KMS Encrypt and KMS Decrypt permissions.
Using the resource component within the policy, you can also specify which CMKs the user, group or role can use to perform the encryption and decryption process. In this example, we can see that the policy will allow the identity associated with the policy to use two different CMKs to encrypt and decrypt data. The first CMK is within the US-East-1 region and the second CMK is within the EU-West-2 region.
Finally, you can assign permissions using grants alongside key policies. I've mentioned grants a couple of times already, but in essence, they allow you to delegate your permissions to another AWS principal within your AWS account. Much like the key policy, grants are another resource based method of access control to the CMKs. The grants themselves need to be created using the AWS KMS APIs. It's not possible to create them using the AWS Management Console and these grants are then attached to the CMK, much like key policies are. Within the key policy of the CMK, you will see the Sid which allows the users of the CMK to also perform three grant actions, kms:CreateGrant, kms:ListGrants and kms:RevokeGrant.
When issuing the CreateGrant API, a number of different parameters are also issued such as the CMK identifier. The grantee principal to gain the permissions and the required level of operations that the grantee can perform include the following on screen. Once the grant is active, the principal or grantee can then adopt the permissions programmatically based on the level of access provided within the grant. Also, after the grant has been created, a GrantToken and a GrantID is issued. When a grant is created, there may be a delay in being able to use the permissions and this is due to the fact that eventual consistency has to take place. To get around this, you can use the GrantToken with some APIs which would allow the grantee to perform the operation specified within the grant with immediate effect without having to wait for eventual consistency to complete.
I gave an example earlier relating to EC2 and EBS whereby another AWS service can use grants to gain access to and use a CMK. I will now provide a demonstration of how the grantee of a grant can be an IAM user to show how grant permissions work.
Start of demonstration 1
Okay so for this demonstration, we're going to use two different users, one user that has access to user CMK and create grants and another user that has no IAM policies at all and isn't explicitly allowed access within the CMK policy either. So let's go ahead and take a look at the CMK we're going to be using first. Go down to encryption keys and we're going to be using this demo key. If we have a look at the policy of this CMK, scroll down and take a look, then we can see that the users within this policy are listed here and we have a user called Alice and Alice can also create grants as well as we can see down here and here's the permission CreateGrant. So we're going to be using the user Alice.
So let's now create an entirely new user with no permissions at all. We'll call this user Bob. We'll give them programmatic access because we'll be using the AWS CLI for this demonstration. We won't create any permissions or attach them to any groups. And as we could see here, the user has no permissions. Create user and we have their access key here and their secret access key.
So what I'm going to do now I'm going to swap across to my terminal and I'm going to set them up a profile on my AWS CLI. Okay so what I need to do is type in aws configure --profile of Bob and this will ask us for the access key ID so we can copy and paste that in and the same for the secret access key ID. It will then ask us for the default region name. Our CMK is in us-east-1 so it'll accept that as the default and also the default output format. So now we have two users, Alice and Bob, and Alice is already setup as a profile on the CLI and we've just setup Bob as well. As we know, Bob doesn't have any permissions within the key policy of the CMK and he doesn't have any permissions within IAM either.
So let's just do a quick test with Bob. We'll try and encrypt something using the CMK ID and it will fail so let's just take a look at that. So if I type in aws kms encrypt using plaintext and we'll encrypt CloudAcademy using the key-id alias of DemoKey which is the name of my CMK using the profile of Bob and there we can see an error has occurred access denied. That's because Bob doesn't have any encrypt permissions. So if we do the same but this time with Alice, so if we change the profile to Alice, then we can see that it has encrypted the file using this CiphertextBlob here. So that file is now encrypted and Alice can do it because she is listed as a user within the key policy for that CMK.
Okay, let me just clear the screen. So now what I want to do is use grants to allow Bob access to encrypt and decrypt data and this would be issued by the user Alice. So the command to do this is as follows so it's aws kms create-grant using the key-id and we need the ARN of our key here so if we just go across, select our CMK, we have our ARN here so paste that in. We'll then need to add the grantee-principal and this will be the person who is actually going to gain this access and again we need the ARN of the user. I'll go ahead and find Bob, copy his ARN, paste that in. Then we need to specify the operations which is the actual access that's going to be given so we're want to grant encrypt and decrypt access and this is going to be issued by the profile of Alice. So Alice is using grants to allow Bob to give access of encrypt and decrypt which is access that Alice has. And we could see that that now works.
We now have a GrantToken and also a GrantId as well. And we can use this information to then perform encryption and decryption straight away using the user Bob. So let me now show you how that works. So now we have the GrantToken and the GrantId. What we can do is encrypt or decrypt data. So let's go ahead and try and encrypt a new file with Bob's profile. So to do this we type in aws kms encrypt --plaintext and "Friday". We add the key-id. We have the key-id up here so I'll just copy and paste that. And then we need to issue the grant-tokens and here I need to add in the GrantToken that was generated which is this block of text so I'll paste that in. And then finally because we want to encrypt with Bob, we'll need to add Bob's profile at the end. As we can see, we have successfully encrypted that file of Friday. So whereas before Bob was unable to encrypt, we have now used the GrantToken which was generated by Alice to allow Bob access to encrypt data.
So just to run through what we've done in this demonstration, we had Alice who is a user within the key policy of a CMK. We then created a new user Bob who had no IAM policies attached and he wasn't listed within the key policy. We then tested that Bob wasn't able to encrypt anything. We then confirmed that Alice could. We then created a grant using Alice's profile allowing access to Bob for encrypt and decrypt and there are other permissions there as well such as generate data keys, etc. We just allowed encrypt and decrypt. We then used the GrantToken that was generated from the create-grant to allow Bob to encrypt a file using the new permissions that he gained through the grant. So once you understand the methodology of how you can grant these additional permissions, it's a fairly simple process to go ahead and allow other principals to use the CMK based on the permissions that you have.
End of demonstration 1
I now want to show you how to create a CMK using the Management Console from scratch and what the final key policy looks like and how key administrators, users and grants all fit in.
Start of demonstration 2
Okay so I've just logged in to my AWS account and first of all I'll need to go to Identity and Access Management which is where KMS can be found. And if we go down the left-hand side on the menus down to encryption keys and this is essentially KMS. This is the KMS function within IAM. Now to create a new CMK, we go up to the blue button here that says create key and we need to add an alias and a description so I'm just going to call this DemoKey and description This is a demo. If we click on advanced options, here we can see different key material origins and I'll talk more about the difference between KMS and external origins in the following lecture. So for this demonstration, I'm just going to select the key material origin of KMS and this will allow KMS to generate the key material. If we click on next step, here we can add tags. For this demonstration, I'm just going to leave them as blank.
And now it's asking us to define the key admins, so essentially who should be the administrators of these keys. And remember as I explained earlier, the key administrators aren't actually able to use the CMK to encrypt and decrypt data. So let me just pick a couple of users here, go down to the next step, and now it'll ask me to define the users of the CMK. So these are the identities that can actually perform encryption and decryption using this CMK. So again I'll just pick a couple of users, click on next step, and now we can look at the key policy that's being created based on the parameters that I have selected.
So if we look at the different sections here, firstly this Sid Enable IAM User Permissions so what we have here is an Allow for the root account or KMS access to this particular CMK. So as I discussed earlier, this entry within the policy ensures that you can use IAM policies to govern access to this CMK. If we scroll down, the next section shows the key administrators for this CMK and here are the two identities that I selected. And if we look at the actions, we can see a number of different KMS actions, but there is no kms:Encrypt and no kms:Decrypt because the key administrators aren't actually able to use the key for encryption. We scroll down to the next section of the policy and this section defines the actual users of the policy so whoever is listed here under the principal section can actually use this CMK to encrypt data and decrypt data. And if we look at the actions, we can see here kms:Encrypt and kms:Decrypt and GenerateDataKeys, etc. Whereas you'll find that these permissions aren't actually within the administrator list. As you can see, there's no kms:Encrypt. So that's the users of the CMK. And finally, this section relates to grants. So this also allows whoever has been added to the user section above, which are these two accounts here, it allows them to create grants and generate grants for the CMK. And then if we click on finish, that's it.
The CMK is created and we can see here that the status is enabled. And if we click on the DemoKey, it would just bring up some different information. So we have the ARN of the key itself. We can see that the status is enabled. And if we scroll down, we can see the key administrators. And there's a checkbox here that allows the key administrators to delete this key. If you don't want a key deleted, then you can simply uncheck that box. Scroll down further, we can see the users of the key as well. Any tags that you added would also be there. And that's it, it's as simple as that. So it's a very simple method to create your CMK, give it a name, add any tags that you need, add the key administrators, add the users, and then select finish, and then you will have your CMK.
End of demonstration 2
The overall access of understanding who has access to a CMK in KMS can be a little confusing as there are three potential ways of gaining access and using a CMK, through the key policy, with IAM policies and also Grants. And determining the correct level of access means you need to understand how they all work together. So let's look at a simple example to ensure we understand some key points. In this scenario, we have three CMKs and four users.
- CMK-A key policy provides access to the root account which as we know also enables IAM policies to be used in conjunction with the key policy.
- CMK-B key policy allows access to Bob and Charlie.
- CMK-C key policy provides access to the root account. Access is explicitly denied for Bob, Charlie and David, but full access is given to Alice.
- Alice's IAM policy allows all KMS actions to CMK-A and CMK-B.
- Bob has no IAM policy
- Charlie's IAM policy allows KMS encrypt access to CMK-A
- and David's IAM policy allows all KMS actions to CMK-B and CMK-C.
So let's now look at each of these user's access and what they have access to, starting with Alice.
Alice's access to CMK-A is successful as her IAM policy allows all KMS actions against CMK-A and CMK-A allows for IAM policies to be used. Her access to CMK-B provides no access as the key policy for this CMK does not allow for IAM policies to be used. And her access to CMK-C is successful as the key policy allows her access despite her having no IAM policy relating to permissions.
Now let's take a look at Bob. His access to CMK is denied as there are no explicit entries in the key policy for Bob's access and he has no IAM policy. His access to CMK-B is successful as the key policy allows him access despite him having no IAM policy relating to permissions and access is denied to CMK-C due to explicit deny actions within the key policy and an explicit deny will always overrule any other allow.
Now let's look at Charlie's access. For CMK-A, he has encrypt access only which is given through his IAM policy and IAM policy permissions are allowed. For CMK-B, access is also successful as the key policy allows him access. His IAM policy permissions are irrelevant as the CMK does not allow for IAM policies to be used. And his access to CMK-C is denied due to the explicit deny actions within the key policy and an explicit deny will overrule any other allow.
And finally David's access. He has no access to CMK-A as neither the key policy or his IAM policy provides permissions. He has no access to CMK-B as the key policy for this CMK does not allow for IAM policies to be used and access is also denied to CMK-C due to explicit deny actions within the key policy.
That now brings me to the end of this lecture covering access control permissions for KMS. Coming up next, I shall be looking at key management within KMS.
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.