Using the Secrets Manager Cache with .NET

Want to learn more about AWS Lambda and .NET? Check out my A Cloud Guru course on ASP.NET Web API and Lambda.

Full source code available here

I’ve written a few blog posts about Secrets Managers, in all I used the AmazonSecretsManagerClient. Each time you use AmazonSecretsManagerClient to request a secret, it makes a call to the AWS Secrets Manager service and retrieves the secret.

If you are like most users, your secrets don’t change very frequently, meaning multiple requests to the AWS Secrets Manager service in a short time are a waste.

You could use an in-memory cache to cache the secrets, but the AWS SDK has a built-in class to help you instead.

The SecretsManagerCache, lets you make requests for secrets. If they are in the cache, it returns the cached value. If they are not, a request is made to the Secrets Manager service, they are subsequently cached for future requests.

You can specify how long to cache secrets for, how many can be cached, and which version of a secret to retrieve.

Under the covers, the SecretsManagerCache uses the AmazonSecretsManagerClient to make requests to the AWS Secrets Manager service. If you don’t pass in an instance of the AmazonSecretsManagerClient to the SecretsManagerCache constructor, one will be created for you with the default configuration. I prefer to create my own instance of AmazonSecretsManagerClient so I can specify the region to use.

1. Create the secret

Create the secret using the following command -

aws secretsmanager create-secret --name my-credentials --secret-string '{\"username\":\"bryan\",\"password\":\"A-COMPLEX-PASSWORD123!\"}'

2. Create a console application

From the command line run -

dotnet new console -n MySecretsManagerCacheApp

Add the AWSSDK.SecretsManager.Caching package to the project -

dotnet add package AWSSDK.SecretsManager.Caching

3. Update the code

Below is a simple example of retrieving a secret from the AWS Secrets Manager service, caching it, and then trying to retrieve the secret again. The code does NOT handle any error cases.

 1using Amazon;
 2using Amazon.SecretsManager;
 3using Amazon.SecretsManager.Extensions.Caching;
 5namespace MySecretsManagerCacheApp;
 7public static class Program {
 8    public static async Task Main(string[] args) {
 9        string secretId = "my-credentials";
11        IAmazonSecretsManager client = new AmazonSecretsManagerClient(RegionEndpoint.USEast1); // us-east-1
13        SecretCacheConfiguration cacheConfiguration = new SecretCacheConfiguration
14        {
15            CacheItemTTL = 20000, // 20 seconds
16            VersionStage = "AWSCURRENT",
17        };
19        SecretsManagerCache cache = new SecretsManagerCache(client, cacheConfiguration);
21        Console.WriteLine($"First request {await cache.GetSecretString(secretId).ConfigureAwait(false)}");
22        Console.WriteLine("Disconnect your computer from the internet, and press any key...");
23        Console.ReadKey();
24        Console.WriteLine($"Second request {await cache.GetSecretString(secretId).ConfigureAwait(false)}");
25    }

4. Run the application

Run the application, and after it retrieves the secret, it stores it in the cache for 20 seconds. Then the application pauses. During this time disconnect your computer from the internet.

Press any key to resume the application.

If you did this within 20 seconds, the application will retrieve the secret from the cache.

Full source code available here

comments powered by Disqus