Secure Your Data in Azure with BYOK

Ambidextrous
6 min readOct 10, 2023

--

Bring Your Own Key (BYOK) is a security measure where a user/organization encrypts their data (residing on the service provider’s platform) with their own generated keys (customer-managed keys) rather than relying on the keys generated by the service provider. This measure is especially useful in today’s age where we have high adoption of public cloud platforms, (such as Azure, AWS, GCP, etc.) and companies working in sensitive areas such as healthcare, defense can have extra security and peace of mind, knowing that they are always in full control of their data.

Recently, one of my healthcare clients put a requirement that they want to use their own keys to encrypt their data residing in Azure. In this case, we are ingesting client data in a nightly batch, processing it, and then storing it in an Azure Postgres database. The client then uses custom visualization apps to analyze this data. With BYOK, they wanted the capability that in case of a breach/security incident, they could instantly make the data unreadable.

Here is the simplified architecture for this:

Azure Postgres provides full support for BYOK. By default, Azure encrypts the data at rest using Microsoft-managed keys. These keys are symmetric keys based on 256-bit AES encryption and are also known as data encryption keys (DEK). When we use customer-managed keys (also known as key encryption keys (KEK) in Azure), Azure uses the customer-managed KEK to encrypt its internal DEK’s which in turn are internally used to encrypt the data. Since we need the KEK to decrypt the DEK’s, the KEK is the single point via which the customer can control the decryption of data. If KEK is deleted or made unavailable, the data in the database cannot be accessed.

Here are a few constraints of using BYOK with Azure Postgres and Azure Key Vault:

  1. Both Azure Key Vault and Azure Postgres must belong to the same Azure tenant. Cross-tenant capabilities are not supported at this moment
  2. The Azure KeyVault must have soft-delete (with 90 days of retention) and purge protection enabled
  3. The customer-managed key needs to be an asymmetric key of type RSA 2048
  4. Supported key types for importing self-generated keys (.pfx, .byok and .backup)

Here is a sample implementation of this solution:

  1. Use this sample terraform script to create the resources in the Azure Cloud. As you can see in the below diagram, the script created a resource group, an Azure Postgres Single Server, and an Azure Key Vault instance

2. Now, we will import out the pfx key (which consists of a private key and a certificate) to the key vault

3. Next, we will configure the Azure Postgres database to use this uploaded key for data encryption. We select the key vault and the key and click Save to save our changes

Note: You may get an error at this step, complaining that the database does not have permission to view the key vault/key. In this, case we need to create an access policy in the keyvault to give our database permission to access the key. Create an access policy that has permissions to perform Get, Wrap Key, and Unwrap Key operations on the key vault and then select the database name as the principal. Now, the database server will be able to access the key.

Note: Another common error faced in this process is that we are unable to find the database principal while creating the access policy. In case you are facing this issue, do two things: 1. Take a break of 5 minutes and try again. Sometimes, there is a delay in the syncing. 2. Make sure you have full access to the vault, if not update the access policy to give yourself full permissions. These things worked for me

4. Now, just restart the server and we are good to go. Our data is now encrypted with the personal key which we uploaded to the vault. To verify this, we can perform a quick test. Here, is our sample database and a quick screenshot that we are able to query it.

5. Next, we will go to the key vault and delete our key. No need to worry, remember we have the soft-delete enabled. We can always recover this key in future within the next 90 days

6. After around 5–10 minutes, you will see that the database state has changed from Available to Inaccessible. Bingo! This is what we wanted. Now, no one can query the database and access its data. If we try to access it through a tool such as pgAdmin we get an error that the tool cannot connect to the server

7. In order to bring the database back to the Available state, we need to recover our key and then revalidate the key in the Security -> Data Encryption section.

Even though BYOK is an excellent security measure that provides us more control over how our data is encrypted, there are still a few points to consider before using BYOK in your platform:

i . BYOK provides the client control over the key generation, rotation, and deletion aspects. But, how and when the data is being encrypted is still being managed by the service provider e.g: Azure

ii. BYOK comes with the extra overhead of managing the key generation, rotation and securely managing the key. Consider using the Azure Key vault to generate and store the key, rather than creating it manually as it limits the exposure of the key

iii. As we are managing our own key, there is a risk of key loss. Organizations should implement proper safeguards and backup mechanisms to mitigate this risk

iv. BYOK solutions are often tied to specific cloud service providers, and thus potentially create vendor lock-ins

I hope this blog helped you. You can refer to my GitHub for the code used in this exercise and here are some references for further reading.

References:

  1. https://github.com/ambidextrous-dev/terraform-byok-azure
  2. https://learn.microsoft.com/en-us/azure/postgresql/single-server/concepts-data-encryption-postgresql
  3. https://cdn2.hubspot.net/hubfs/1761386/Unbound_Docs_/CYOK_eBook_Control_Your_Own_Keys_in_the_Cloud_with_Unbound.pdf
  4. https://baptistout.net/posts/convert-jwks-modulus-exponent-to-pem-or-ssh-public-key/

--

--