dotnet / AspNetCore.Docs

Documentation for ASP.NET Core
https://docs.microsoft.com/aspnet/core
Creative Commons Attribution 4.0 International
12.58k stars 25.29k forks source link

Guidance for managing KeyVault Key Rotation when using the DataProtection API #29496

Open philip-reed opened 1 year ago

philip-reed commented 1 year ago

Hi,

I'm trying to find guidance on how to manage the rotation of a DataProtection key stored in Azure KeyVault when applying this implementation:

https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview?view=aspnetcore-7.0#protectkeyswithazurekeyvault

Specifically this section:

The keyIdentifier is the key vault key identifier used for key encryption. For example, a key created in key vault named dataprotection in the contosokeyvault has the key identifier https://contosokeyvault.vault.azure.net/keys/dataprotection/. Provide the app with Get, Unwrap Key and Wrap Key permissions to the key vault.

If the dataprotection key in KV is rotated, either manually or via a rotation policy applied in the Azure Portal, what happens? How does that impact existing authenticated users?

Is this somehow managed silently, or will all users be de-authenticated when the KeyVault KeyIdentifier expires in lets say ~2years time?

KeyVault looks like it supports auto rotation which is great, but I would like to avoid de-authenticating users if possible:

https://learn.microsoft.com/en-us/azure/key-vault/keys/how-to-configure-key-rotation#key-rotation-policy

https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/implementation/key-management?view=aspnetcore-7.0#key-expiration-and-rolling

Thanks.


Document Details

Do not edit this section. It is required for learn.microsoft.com ➟ GitHub issue linking.

philip-reed commented 1 year ago

Possibly related, but i'm not sure I understand this well enough yet to know for sure:

https://stackoverflow.com/questions/65235299/what-is-the-strategy-of-data-protection-key-rotation-with-multiple-pods

maxbeaudoin commented 1 year ago

Any update on this?

We went ahead with a Rotation Policy in Azure but it's unclear how .NET's Data Protection will behave in 90 days.

services.AddDataProtection()
    .PersistKeysToAzureBlobStorage(...)
    .ProtectKeysWithAzureKeyVault(...);
FilipDeVos commented 11 months ago

Any update? We are implementing this and there is no guidance on how to set KeyVault key rotation.

tonycoelho commented 11 months ago

The docs do leave a lot to be desired regarding Key Vault key rotation, but to quickly answer the question... yes when protecting the data protection keys with ProtectKeysWithAzureKeyVault, you CAN use automatic key rotation in Key Vault. AzureKeyVaultXmlEncryptor stores the URI to the version of the Key Vault key used to encrypt the data protection keys in the kid property. See line 70 at https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/extensions/Azure.Extensions.AspNetCore.DataProtection.Keys/src/AzureKeyVaultXmlEncryptor.cs

Here is an example:

<?xml version="1.0" encoding="utf-8"?>
<key id="80732141-ec8f-4b80-af9c-c4d2d1ff8901" version="1">
  <creationDate>2015-03-19T23:32:02.3949887Z</creationDate>
  <activationDate>2015-03-19T23:32:02.3839429Z</activationDate>
  <expirationDate>2015-06-17T23:32:02.3839429Z</expirationDate>
  <descriptor deserializerType="{deserializerType}">
    <descriptor>
      <encryption algorithm="AES_256_CBC" />
      <validation algorithm="HMACSHA256" />
      <enc:encryptedSecret decryptorType="{decryptorType}" xmlns:enc="...">
        <encryptedKey>
          <!-- kid is the URI to the version of the Key Vault key used to encrypt the data protection key -->
          <kid>https://mykeyvault.vault.azure.net/keys/DataProtectionKey/8ee9ef177bc4abca6103f49ba3bcb2d</kid>
          <value>AQAAANCM...8/zeP8lcwAg==</value>
        </encryptedKey>
      </enc:encryptedSecret>
    </descriptor>
  </descriptor>
</key>

Data protection will try all the keys (data protection keys, not Key Vault key) when unprotecting a value and since the kid points to a specific version of the Key Vault key used to encrypt the data protection keys, as long as that version isn't deleted it can be used to decrypt the keys.

One thing to note is that you should probably use a similar rotation interval for both keys (i.e., data protection keys and Key Vault key) but where the Key Vault key rotates more frequently than the data protection keys to ensure you are using a new Key Vault key at the time of data protection key rotation.

FilipDeVos commented 11 months ago

Thanks, this comment should be copy pasted into the documentation :)

samholder commented 7 months ago

Hi. I know this is a reasonably old issue, but I have some additional questions which are related.

If you would rather I raise a new issue, let me know.

Its not clear from the documentation if rotating the key vault key will cause all the data protection keys to be regenerated with the new key vault key.

If not then what happens when a key vault key is compromised? how do we ensure the data is not accessible via that key vault key any more?

We are using the data protection API with the keys stored in blob storage and the keys protected with a key vault key. We are using it to encrypt data stored in blob storage, with a long lifetime. The DP keys rotate every 90 days and currently the key vault key is not rotating, but we would like to rotate it. It seems from this discussion that we can allow auto rotation of the key vault keys (which is good) but will the data protection keys be reencrypted with the latest key at any point if the key vault key is rotated or revoked?

ztatvialto commented 4 months ago

Some one mentioned if you use the Azure Key Vault Key to protect your DP keys, you don't need to care the protection key rotation, it would be automatically done by Azure Key Vault Key.

But if you upload your cert to KeyVault and use it to protect you DP keys, you have to renew it manually. As mentioned by tonycoelho, the DP key stored the version, even you renewed the cert in KeyVault, it should be easy to retrieve the old one and unprotect old DP keys. I haven't tested and review the codes, but I'm facing the same issue to wonder if I renew the cert is there any impact to existing data, so I will test it.

update: the DP Key refers to a versioned key in Key Vault, so that you can decrypt the data with previous DP Key, this is done by DPAPI you don't need any special operation, you just need to keep the DP Key is existing on Filesystem or Blob or DB or somewhere, since the encrypted data refers to a DP Key.

and I verified even the cert is expired and replaced by a renewed cert, since the old cert is stored as a previous version, it's same like the VersionControlSystem, the DPAPI can retrieve the old cert to decrypt DP Key if it is required, and there is no error to decrypt with an expired cert, but if the DPAPI need to generate a new DP Key, the cert must be valid, so you should let the DPAPI always use the latest cert.