I'm wondering if an Azure web application can have access to multiple key vaults? This is because one of our web applications has multiple database connection strings and each of the databases has columns encrypted with always encrypted and the column encryption keys will be stored in their own key vaults per database. If this is possible, how does the web application know which key vault to access to get the column encryption key for the respective database it's connecting to?
Currently the web application has access to one key vault and all of the databases are encrypted with the same column encryption key which is in this key vault. But I want to split this out so each database has it's own key vault and respective column encryption key for better security. The web application obtains access to the key vault via Azure Active Directory with the client id and secret mechanism. I've played around with adding the Azure Active Directory application to the multiple key vaults using the key vault access policy but not sure if this is correct/will work.
The code I'm using to wire up the column encryption key with the web application (which appears to be key vault agnostic):
public static void InitializeAzureKeyVaultProvider()
{
var clientId = ConfigurationManager.AppSettings["AuthClientId"];
var clientSecret = ConfigurationManager.AppSettings["AuthClientSecret"];
_clientCredential = new ClientCredential(clientId, clientSecret);
SqlColumnEncryptionAzureKeyVaultProvider azureKeyVaultProvider =
new SqlColumnEncryptionAzureKeyVaultProvider(GetToken);
Dictionary<string, SqlColumnEncryptionKeyStoreProvider> providers =
new Dictionary<string, SqlColumnEncryptionKeyStoreProvider>
{
{SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, azureKeyVaultProvider}
};
SqlConnection.RegisterColumnEncryptionKeyStoreProviders(providers);
}
private static async Task<string> GetToken(string authority, string resource, string scope)
{
var authContext = new AuthenticationContext(authority);
var result = await authContext.AcquireTokenAsync(resource, _clientCredential);
if (result == null)
{
throw new InvalidOperationException("Failed to obtain the access token");
}
return result.AccessToken;
}
Thoughts?