W4k.Extensions.Configuration.Aws.SecretsManager 0.2.0-alpha

This is a prerelease version of W4k.Extensions.Configuration.Aws.SecretsManager.
There is a newer version of this package available.
See the version list below for details.
dotnet add package W4k.Extensions.Configuration.Aws.SecretsManager --version 0.2.0-alpha
NuGet\Install-Package W4k.Extensions.Configuration.Aws.SecretsManager -Version 0.2.0-alpha
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="W4k.Extensions.Configuration.Aws.SecretsManager" Version="0.2.0-alpha" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add W4k.Extensions.Configuration.Aws.SecretsManager --version 0.2.0-alpha
#r "nuget: W4k.Extensions.Configuration.Aws.SecretsManager, 0.2.0-alpha"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install W4k.Extensions.Configuration.Aws.SecretsManager as a Cake Addin
#addin nuget:?package=W4k.Extensions.Configuration.Aws.SecretsManager&version=0.2.0-alpha&prerelease

// Install W4k.Extensions.Configuration.Aws.SecretsManager as a Cake Tool
#tool nuget:?package=W4k.Extensions.Configuration.Aws.SecretsManager&version=0.2.0-alpha&prerelease

W4k.Extensions.Configuration.Aws.SecretsManager

W4k.Either Build NuGet Badge CodeQL

Configuration provider for AWS Secrets Manager.

Installation

dotnet add package W4k.Extensions.Configuration.Aws.SecretsManager

Usage

var builder = WebApplication.CreateBuilder(args);

// add AWS Secrets Manager Configuration Provider for specific secret
builder.Configuration.AddSecretsManager(
    "my-secret-secrets",
    c => c.ConfigurationKeyPrefix = "AppSecrets");

// ... and then bind configuration using `ConfigurationKeyPrefix` = "AppSecrets"
builder.Services
    .AddOptions<Secrets>()
    .BindConfiguration("AppSecrets");

Additionally, you can pass SecretsManagerClient to the provider:

// passing custom `IAmazonSecretsManager` (e.g. with custom credentials)
var client = new AmazonSecretsManagerClient(/* ... */);
builder.Configuration.AddSecretsManager(
    "my-secret-secrets",
    client,
    c => c.ConfigurationKeyPrefix = "AppSecrets");

Configuration

Optional secret

When adding configuration source, it is mandatory by default - meaning if secret is not found or it's not possible to load it, exception is thrown. To make it optional, set IsOptional to true:

builder.Configuration.AddSecretsManager("my-secret-secrets", isOptional: true);

Secret Version

If omitted, latest version of the secret will be used, however it is possible to specify custom version or stage:

builder.Configuration.AddSecretsManager(
    "my-secret-secrets",
    c =>
    {
        c.Version = new SecretVersion { VersionId = "d6d1b757d46d449d1835a10869dfb9d1" };
    });

Configuration key prefix

By default, all secret values will be added to the configuration root. To prevent collisions with other configuration keys, or to group secret values for further binding, it is possible to specify configuration key prefix as follows:

builder.Configuration.AddSecretsManager(
    "my-secret-secrets",
    c => 
    {
        c.ConfigurationKeyPrefix = "Clients:MyService";
    });

With example above, secret property of name Password will be transformed to Clients:MyService:Password. When binding your option type, make sure path is considered or that you bind to the correct configuration section.

Secret processing (parsing and tokenizing)

By default AWS Secrets Manager stores secret as simple key-value JSON object - and thus JSON processor is set as default. In some cases, user may want to specify custom format, either complex JSON object or even XML document.

In order to support such scenarios, it is possible to specify custom secret processor:

builder.Configuration.AddSecretsManager(
    "my-secret-secrets",
    c => 
    {
        // implements `ISecretsProcessor`
        c.Processor = new MyCustomSecretProcessor();
    });

There's helper class SecretsProcessor<T> which can be used to simplify implementation of custom processor (by providing implementation of ISecretStringParser<T> and IConfigurationTokenizer<T>).

Configuration key transformation

It is possible to hook configuration key transformation, which is used to transform tokenized configuration key. By default only KeyDelimiterTransformer is used.

KeyDelimiterTransformer transforms "__" to configuration key delimiter, ":".

To add custom transformation, use property KeyTransformers:

builder.Configuration.AddSecretsManager(
    "my-secret-secrets",
    c => 
    {
        // implements `IConfigurationKeyTransformer`
        c.KeyDelimiterTransformer.Add(new MyCustomKeyTransformer());
    });

It is also possible to clear transformers by simply calling Clear() method.

c.KeyDelimiterTransformer.Clear();

Refreshing secrets

By default, secrets are not refreshed. In order to enable refreshing, you can configure ConfigurationWatcher property:

builder.Configuration.AddSecretsManager(
    "my-secret-secrets",
    c => 
    {
        // implements `IConfigurationWatcher`
        c.ConfigurationWatcher = new SecretsManagerPollingWatcher(TimeSpan.FromMinutes(5));
    });

Watcher won't be started when initial load of secret fails.

Be aware that querying secret value from AWS Secrets Manager is not free. See AWS Secrets Manager pricing for more details.

Startup behavior

It may happen that there's connection issue with AWS Secrets Manager. In order to prevent unnecessary hangs, it is possible to configure startup timeout:

builder.Configuration.AddSecretsManager(
    "my-secret-secrets",
    c => 
    {
        c.Startup.Timeout = TimeSpan.FromSeconds(42);
    });

If secret is not loaded within specified timeout AND source is not optional, exception will be thrown.

Logging

It is possible to configure logging for the provider:

builder.Configuration.AddSecretsManager(
    "my-secret-secrets",
    c => 
    {
        // using Microsoft.Extensions.Logging
        c.LoggerFactory = LoggerFactory.Create(logging => logging.AddConsole());
    });

By default logging is disabled (by using NullLoggerFactory).

Since logging happens during host build phase (before application is fully built), it's not possible to use final application logger. Perhaps you will need to configure logging twice - once for the provider and once for the application.

Acknowledgements

This library is inspired by Kralizek.Extensions.Configuration.AWSSecretsManager.

Alternative approaches

When using AWS Fargate (ECS), you can configure Task Definition to use Secrets Manager as a source of environment variables. This approach is described in Passing sensitive data to a container / Using Secrets Manager.

Alternative packages


Setting icons created by Freepik - Flaticon

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.0 94 1/24/2024
0.2.0-alpha 67 1/21/2024
0.1.0-alpha 68 1/14/2024