'AWS Secret Manager caching in ASP.NET MVC application

I have an ASP.NET MVC application. I have used secret manager to fetch latest secret for database passwords. I am able to fetch password from secret manager in global.asax AppStart method & set same in connection string.

Now I have also used Secret Manager Caching library to cache secrets to avoid multiple calls to secret manager. But I have set password rotation for lets say five days. So password will get updated automatically after 5 days in database as well as in secret manager then it will throw exception that incorrect credentials.

So what will be the ideal place to call secret manager record - in app start it will call once but lets say password got change then it will not call secret manager again so how to get latest password.

Appstart method:

    using (var secuser = new SecretCacheManager())
    {
        var secretResult = secuser.GetSecret("secret/key").Result;
        var connection = ConfigurationManager.ConnectionStrings["MyConString"];
        configurationReadOnlyField.SetValue(connection, false);
        connection.ConnectionString = connection.ConnectionString.Replace("PASSWORD_PlaceHolder", secretResult.Password);            
    }

Secret Manager caching code

using Amazon.SecretsManager;
using Amazon.SecretsManager.Extensions.Caching;
using Newtonsoft.Json;
using System;
using System.Threading.Tasks;


namespace CachingLibrary
{
    public class SecretCacheManager : IDisposable
    {
        public readonly IAmazonSecretsManager secretsManager;
        public readonly SecretsManagerCache secretsManagerCache;

        public void Dispose()
        {
            secretsManager.Dispose();
            secretsManagerCache.Dispose();
        }

        public SecretCacheManager()
        {
            secretsManager = new AmazonSecretsManagerClient();
            secretsManagerCache = new SecretsManagerCache(this.secretsManager);
        }

        public async Task<SecretModel> GetSecret(string secretName)
        {
            var response = await secretsManagerCache.GetSecretString(secretName);
            return JsonConvert.DeserializeObject<SecretModel>(response);
        }       
    }

    public class SecretModel
    {
        public string Username { get; set; }
        public string Password { get; set; }
        public string Engine { get; set; }
        public string Host { get; set; }
        public string Port { get; set; }
        public string Dbname { get; set; }
    }
}

Below line first check if records is in cache or not if not then it call actual secret manager

 var response = await secretsManagerCache.GetSecretString(secretName);


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source