Explore critical differences in handling customer-managed encryption keys (CMKs) across AWS, Azure, and GCP to avoid security misconfigurations and protect your data effectively.
Why are we here?
A customer-managed encryption key (CMK) is an encryption key created, managed, and owned by the customer. This gives the customer control over its access management—that is, determining who / what may access it and what actions they can perform.
A CMK is distinct from provider-managed keys, where the cloud service provider manages the key lifecycle and access.
CMKs are available across various cloud service providers such as AWS, Azure and GCP.
There’s a significant difference between the paradigm applied to encryption and decryption with CMKs in AWS and the one which is applied in Azure and GCP. A lack of understanding of this difference may have consequences if it goes unnoticed by security practitioners. In this blog, we delve into the differences and why the distinction is important.
Using CMKs in AWS
In AWS, CMKs are available with AWS Key Management Service (KMS).
When a data resource, such as an S3 bucket, is encrypted using a CMK, accessing the data (such as through an S3 request) involves a decryption process. The AWS KMS action will be performed using the credentials of the identity that initiated the data access request. Here you can find more information about how this works and the aws:CalledVia condition key. We’ve also done our own review of this condition key as well as others that are significant to know in a previous post.
The reason why this operation method is important is its implications when managing access to data.
In AWS, even if you grant a principal access to retrieve data (such as providing access to s3 for an object in a bucket), the principal will still receive an Access Denied error if the object is encrypted with a CMK with which they are not allowed to decrypt. This is because the principal credentials are used for the decryption process and thus it’s required they have the necessary permissions.
This dual requirement adds an extra layer of security as both permissions are necessary to access the encrypted data.
This is very significant as usage of managed policies in AWS is pretty popular even though it’s usually a very poor practice. For example, a principal may be granted AmazonS3FullAccess if they require access only to very specific buckets. Alternatively, even a user-managed IAM policy could be easily configured with a “*” in the right place (or wrong place, depending how you look at it) and that will enable the principal to have access to all buckets in an account.
If a bucket holding sensitive information is encrypted with a CMK, a principal will still need explicit access to perform kms:Decrypt using that key, even if it has access to retrieve information from all buckets in the account. This significantly reduces the chance of unintentional data access.
Using CMKs in Azure and GCP
The situation in Azure and GCP is quite different when using their storage solutions (storage accounts and cloud storage buckets, respectively), as the principal being used to perform the decrypt operation is not the principal initiating the data access call, which we will now explore.
Being aware of this is important because if you come from an AWS background and then start using Azure or GCP (which happens quite a bit), you may be under the impression that, similarly to AWS, there’s a requirement for having the permissions to use the CMK in order to access the data.
This might lead you to believe that a sensitive Azure storage account or a cloud storage bucket in GCP is protected from principals with a Role that grants access to all storage data in a subscription or project, as long as they don't have access to the CMK. However, this is not actually the case.
Since the principal accessing the data is different from the one initiating the call (which we will explain later), and the accessing principal is granted access to the bucket separately, the initiating principal does not need permissions to use the CMK.
Using a CMK in Azure
CMKs in Azure are created in Key Vault.
In order to encrypt a storage account using a CMK, you will first have to create a managed identity. The identity will then be associated with the storage account and will be the principal used to perform the encryption and decryption actions using the CMK.
Note that to be able to use the CMK for this particular use case, we had to enable purge protection on the key vault:
We actually discovered this requirement “by accident” as we ran into this error message when trying to create the storage account:
As explained in the Azure documentation: “The managed identity that is associated with the storage account must have these permissions at a minimum to access a customer-managed key in Azure Key Vault: wrapkey, unwrapkey, get”
So, you will need to create a custom role allowing for the following permissions:
And then create a role assignment for the managed identity with that role:
Then, as you configure the storage account, you will choose the CMK you want to use for encryption from the key vault AND the managed identity, which will be associated with the storage account for the purpose of encrypting / decrypting:
Using a CMK in GCP
In GCP, the mechanism is similar to the one used in Azure, but slightly different.
The principal performing the encryption / decryption is the cloud storage service agent; you can find its email in the cloud storage settings:
You can then assign it with the Cloud KMS CryptoKey Encrypter/Decrypter Role on the key used for encrypting the bucket, as described here.
And… that’s pretty much it. Now the service agent for cloud storage is able to use the key in order to perform encryption / decryption of its content with the CMK.
What this means for security
The difference shown here between the encryption-related permissions paradigms corresponds with a difference between the AWS approach to permission management and the RBAC (role based access control) employed by Azure and GCP. While the AWS approach may be more complex to manage, it does provide more control mechanisms when it comes to access.
It’s also a great example of how this approach can be both a security advantage and a security liability.
When granting access to encrypted resources, the Azure and GCP approach is easier to manage, because granting permissions to the objects themselves should suffice. Also, there are fewer things to consider, such as managing the permissions to the encryption assets for each principal. This simplicity is great for security as teams can more easily implement compartmentalization of data access.
Additionally, the complexity of managing permissions to the keys may unintentionally create a scenario where an attacker is able to manipulate, hijack the key, and carry out an effective ransomware attack.
On the other hand, a security boundary that requires permissions to a KMS key cannot be established using the CMK. If permission to access data is granted by mistake (which can definitely happen), the encryption won’t prevent it.
Although we’re usually in search of winners vs. losers in these kinds of comparisons, it’s very hard to make a clear determination in this case. However, one thing is clear: knowing the distinction between the two, as well as the pros and the cons for each, is key (pun not intended).
Conclusion
Data protection and access management is a crucial cornerstone of your cloud environment security and also essential to adhere to many compliance standards.
If you’re starting out with encryption in Azure and / or GCP, whether you’re an experienced AWS practitioner or not, remember the difference we discussed here. Be extremely careful with data access permissions granted to principals in your subscriptions / projects.
As always, based on the principle of least privilege, be sure to provide principals only with the permissions they need for their job function, preferably with a custom role and only on the appropriate scope. If possible, this should also be given on the resource level only.
If you have any questions, visit our cloud security page and contact us for more information.