Improving Azure Key Vault Performance With C#

Introduction

In this blog, we are discussing how to improve the Azure key vault performance with real-time scenarios.

Scenario 1. When we have more keys in the key vault.

Assume in the application, that we have 30 secrets, and each and every time, whenever a secret is needed, we are making a call to the key vault. This will bring throttling issues since we are making multiple calls to the key vault. This will directly impact application performance, and it also increases the cost.

Solution

It is good to make one call and get all the keys. For this, we need to store our secrets in Json format, for example.

{"Key1":"value","Key2":"value","Key3":"value"}

once we receive a response from the key vault, parse the json string into an object and use it wherever it is needed.

Scenario 2. Concurrent calls to Azure key vault.

Making concurrent requests to the azure key vault increases the volume of requests, and this leads to a performance issue.

Solution

During application, initialization calls the key vault, stores the response in the cache with an expiration time, and reads the keys from the cache itself.

Code snippet

public string GetSecret(string key)
{
    string ReturnKey;
    if (((Microsoft.Extensions.Caching.Memory.MemoryCache)_cache).Count<0)
    {
        InvokeKeyVault();
        ReturnKey = (string)_cache.Get(key);
       return ReturnKey;
    }
    else
    { 
     _cache.TryGetValue(key, out ReturnKey);
      return ReturnKey;
        
    }
    
}

public string InvokeKeyVault()
{
    try
    {
        MemoryCacheEntryOptions options = new MemoryCacheEntryOptions
        {
            AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60),
            SlidingExpiration = TimeSpan.FromHours(1)  
        }; 
       
            var client = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(async (string auth, string res, string scope)
           =>
      {
          var authContext = new AuthenticationContext(auth);
          var credential = new ClientCredential(clientId, clientSecret);
          AuthenticationResult result = await authContext.AcquireTokenAsync(res, credential);
          if (result == null)
          {
              throw new Exception("error");
          }
          else
          {
              return result.AccessToken;
          }

      }
       ));
         
        var ResponseFromKeyVault = client.GetSecretAsync(KeyVaultURL, KeyName).Result.Value; 
        KeyVaultResponse appsettings = JsonConvert.DeserializeObject<KeyVaultResponse>(ResponseFromKeyVault.ToString());
        _cache.Set("Password", appsettings.Password, options); 

    }
    catch (Exception ex)
    {

    }
    return "Success";
}

Summary

In this blog, we learned about how to handle the Azure key vault performance issues.

I hope that you find it helpful. Eat->Code->Sleep->Repeat.