![Demystifying AWS KMS key rotation](https://assets.community.aws/a/2cdLjdIgfwole6hjjjc81Wnfyrh/feature-jpg.webp)
Staff Pick
Demystifying AWS KMS key rotation
Find the right strategy to rotate your KMS Keys securely without any data loss.
Published Feb 20, 2024
The other day I was discussing with a colleague about the implications of changing KMS keys once the data is already encrypted. The consensus was that there is little literature in that regard. For that reason I'm writing this post to give you some insight on how to deal with KMS key rotation.
Note: This post covers a very specific and advanced level topic. It is assumed that the reader is familiar with AWS KMS service and has hands-on experience using it along other AWS services.
There's no doubt that when it comes to data security at rest, AWS Key Management Service (AWS KMS, or just KMS for short) is the best approach.
- Works with most AWS Services.
- It's simple to set-up.
- Offers a good balance between simplicity of management and key control.
Regarding the balance between easier management and key control, KMS offers three types of keys.
- AWS owned key: Keys owned and managed by AWS. They are the simplest to use but they offer no control to the customer. Also these keys are shared between customers.
- AWS managed key: Keys owned by the customer but managed by AWS. Usually associated with a single AWS Service. These keys live only in the customer AWS account and are not shared with other customers.
- Customer managed key: Keys owned and managed by the customer, a.k.a. us, who are responsible of the lifecycle for the key, where it is used and the key security (configuration of its key policy).
In this post I'm going to talk about this last type of keys, Customer managed keys (CMKs).
Note: Following the recent changes in AWS documentation I'm going to refer to CMKs simply as KMS keys, in opposition to AWS KMS keys used for those keys managed by AWS.
To understand key rotation we must know how keys are made and from what they are made.
For simplicity, I'm assuming that all the keys we are using in this post are of type Symmetric and their key usage is Encrypt and Decrypt.
When we create a KMS key, we choose the key material origin.
- KMS: It's the recommended approach. AWS creates and manages the key material for the KMS key.
- External (Import Key material): You create and import the key material for the KMS key.
- AWS CloudHSM key store: AWS KMS creates key material in the AWS CloudHSM cluster of your AWS CloudHSM key store.
- External key store: The key material for the KMS key is in an external key manager outside of AWS.
Unless we have a very strict security posture, KMS key material is the preferred option for the majority of the cases. AWS CloudHSM key store and External key store are advanced use cases that are not covered by this post.
The main difference between KMS key material and External key material is that in the former AWS is responsible for the creation, custody and rotation of the key material. In the latter, it is our sole responsibility as customers to do all of that. A KMS generated key material never leaves the hardware where it was generated making it very difficult to compromise. On the other hand, for an external customer key material we should take care of securing the generation process as well as storing them in a secure and durable manner.
Knowing these differences is important to know how to effectively rotate KMS keys.
There is not a single way of rotating KMS keys. It depends on the type of key material used and the control we would like to have in the rotation process.
Automatic key rotation
For KMS keys with KMS managed key material it is possible to enable automatic key rotation once a year. This process keeps the same logical resource, our KMS key, but rotates its key material. The old key materials of the key are kept, and the only way to delete them is deleting the KMS key.
From that point forward new encrypt operations will use the new key material of the key, while the decrypt operations will use the key material that was used at the moment of the encryption. This guarantees that any data key encrypted with that KMS key will be able to be decrypted.
Manual rotation could be used in either keys with KMS managed key material and keys with imported key material. Also for keys with imported key material it is possible to accomplish it in two different ways:
For KMS keys with KMS key material and imported key material. This method consist of generating a new KMS key and pointing the KMS alias used in the old key to the new one. That way it is not necessary to make any change in our application code or AWS Services that used that KMS Alias.
When a KMS Alias is pointed to another KMS key, all new encrypt operations will be carried by the new KMS key, but in a similar way that what happens with automatic key rotation, the decryption of data keys encrypted with the old KMS key is guaranteed as long as the old keys exist and were enabled. The decrypt operation uses metadata to know which is the corresponding decryption key.
This method is only valid for KMS keys with imported key material. It consists in uploading new key material to the KMS key. However, unlike Automatic key rotation in KMS keys with KMS key material, for KMS keys with imported key material the old key materials are not kept when a new one is uploaded. This makes it impossible to decrypt any data key encrypted before the key material rotation.
Although it is very difficult to have a KMS key compromised it's not impossible. As we see earlier, AWS managed key material never leaves the hardware where it was generated, but, for customer managed key material it's different.
For KMS keys with external key material the customer must take care of the custody and security of the key material. This includes storing it securely and not disclosing it just like any other secret or password.
Let's see some examples on how to rotate a KMS key depending on where it is used. These examples include how to prevent access to keys with compromised key material.
We used a KMS key
ee740549-6491-47b0-810d-1365b9b52792
with alias my-key
to generate data keys that we will use to encrypt our files. ![](https://assets.community.aws/a/2cdMmglf6w6rktotgClp9WTQFvz/kms-.webp)
We could decrypt our Ciphertext Blob using the same KMS key.
We already have data encrypted with our data key when we realized our KMS key (the key material) has been compromised.
If we simply rotate the key with another one, pointing the alias to the new key all the new data keys we generate will be secured, but the current ones and the data protected with them will be at risk.
This scenario is even worse if we replace the key material. We'll lose access to the data key and the data protected under it.
The right approach then is as follows:
1) Re-encrypt data keys generated with the compromised KMS key. This process doesn't alter the content of the data key, only its encryption, not being necessary to re-encrypt the data it protects. For this we will use a new KMS key
9772c95e-c9c5-43fb-bfcd-f8c4678f9e49
and point the alias my-key
to it.![](https://assets.community.aws/a/2cdNqz5mAztv1VZSGVmEdJ2OBZB/kms-.webp)
2) Disable the compromised KMS key to prevent any decrypt operation.
![](https://assets.community.aws/a/2cdO2uIs2Gm3eY9tHiX7omoAElx/kms-.webp)
3) From that moment only will it be possible to decrypt our data key with the new KMS key.
![](https://assets.community.aws/a/2cdOsi76R2hyeO7Um83jcFkIomj/kms-.webp)
In this scenario we have an S3 bucket `my-bucket-102353703712` with SSE-KMS default encryption key `93237725-c352-41c7-a762-3f001e97c9af`
![](https://assets.community.aws/a/2cdPj5Vsg9l2euzrlvszczsGcV6/kms-.webp)
Any file we put on the bucket is automatically encrypted with this default KMS Key.
We could check that our file is encrypted and the key used for that purpose.
At this point, we need to rotate our KMS key just like in the previous scenario. For S3 buckets the best approach is to re-encrypt our bucket objects once we change the default bucket KMS key.
1) Change the bucket default KMS Key. This process doesn't alter the encryption of the objects that already exist in the bucket. Since we are rotating our KMS Key due to the fact that the key has been compromised, we must take further actions.
![](https://assets.community.aws/a/2cdQQJpdptHg1HPvK4MitlMWLVy/kms-.webp)
2) Re-encrypt bucket objects. To do so we could simply perform a copy operation on the whole bucket.
It is worth to mention that there are many ways to accomplish the re-encryption of all objects in a bucket. The one presented here is one of the simplest, but it could have some limitations. For buckets with thousands or millions of objects, it could be advisable to rely on S3 Batch Operations.
![](https://assets.community.aws/a/2cdQp7Noj5n1sQL4jyDUD4FdaAM/kms-.webp)
3) Finally, we disable the compromised KMS key to prevent further usage.
![](https://assets.community.aws/a/2cdR2PWMZtJAvZTwVrG4VE30elU/kms-.webp)
Since EBS volumes cannot be re-encrypted, the rotation of KMS keys must be approached indirectly. The only way of re-encrypting an EBS volume content is generating a snapshot and then creating a new volume from it using a different KMS key.
Our starting point is an EBS volume encrypted with a KMS key
d6f8b1ee-032c-4244-9d44-827861e6f9fa
.![](https://assets.community.aws/a/2cdRMjT2yZxOjXre9u0GkDDIFOj/kms-.webp)
As in previous examples, we must rotate the KMS key. We proceed as follows:
1) Create a snapshot of the volume.
![](https://assets.community.aws/a/2cdSO0VIN1a3dyRubldhQjxi0By/kms-.webp)
2) Then create a new volume from the snapshot referencing the new KMS key.
![](https://assets.community.aws/a/2cdSQcPdQWo8FBwN0fI6bCp8j47/kms-.webp)
3) Finally, disable the old KMS key and delete the original volume and its snapshot.
![](https://assets.community.aws/a/2cdSHiElPnoS8zCHHciOH6yW5tv/kms-.webp)
The rotation of KMS keys in other AWS services varies from service to service, but in a way or another could be extrapolated from the examples given in this post. For instance, the process to rotate or change the KMS key for an Aurora RDS Cluster consists in taking a cluster snapshot and restoring it while changing its KMS key in a similar fashion as we did with the EBS volume.
Other services though have a simpler rotation process, for example in DynamoDB is as simple and transparent as just specify a new KMS key in the encryption options for the table and the service takes care of the re-encryption process.
As we saw in this post, the chances of getting a KMS key compromised are very low since the AWS generated key material never leaves AWS hardware unencrypted. Customer generated key material should be used only for very specific use cases and the customer is responsible for the custody and durability of the key material.
All in all, it is possible to rotate and block old keys, but it has an operational overhead. The procedure for rotating KMS keys varies from service to service and must be planned and tested carefully.
---