Create a new secret provider
Prerequisites#
The secret providers are configured during the initial application build-up in the Program.cs:
using Microsoft.Extensions.Hosting;
public class Program{ public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); }
public static IHostBuilder CreateHostBuilder(string[] args) { return Host.CreateDefaultBuilder(args) .ConfigureSecretStore((context, config, builder) => { builder.AddEnvironmentVariables(); }) .ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>()); }}This section describes how a new secret store source can be added to the pipeline.
Developing a secret provider#
Install the NuGet package
Arcus.Security.Core.Implement your own implementation of the
ISecretProviderex:using Arcus.Security.Core; namespace Application.Security.CustomProviders{ public class RegistrySecretProvider : ISecretProvider { public Task<string> GetRawSecretAsync(string secretName) { object value = Registry.LocalMachine.GetValue(secretName); return Task.FromResult(value?.ToString()); } public async Task<Secret> GetSecretAsync(string secretName) { string secretValue = await GetRawSecretAsync(secretName); return new Secret(secretValue); } }}Optionally, you can provide an extension for a consumer-friendly way to add the provider. ex:
namespace Microsoft.Extensions.Hosting { public static class SecretStoreBuilderExtensions { public static SecretStoreBuilder AddRegistry(this SecretStoreBuilder builder) { var provider = new RegistrySecretProvider(); return builder.AddProvider(provider); } } }And in the
Startup.cs:.ConfigureSecretStore((context, config, builder) =>{ builder.AddRegistry();})Or, you can use your provider directly.
.ConfigureSecretStore((context, config, builder) => { var provider = new RegistrySecretProvider(); builder.AddProvider(provider);})Now, the secret source is available in the resulting
ISecretProviderregistered in the dependency injection container. ex:using Arcus.Security.Core; namespace Application.Controllers{ [ApiController] public class OrderController : ControllerBase { public class OrderController(ISecretProvider secretProvider) { } }}Note that when your secret provider requires caching, you can wrap the provider in a
CachedSecretProviderat registration: ex:using Arcus.Security.Core.Caching; namespace Microsoft.Extensions.Hosting { public static class SecretStoreBuilderExtensions { public static SecretStoreBuilder AddCachedRegistry(this SecretStoreBuilder builder) { var provider = new RegistrySecretProvider(); var configuration = new CacheConfiguration(TimeSpan.FromSeconds(5)); return builder.AddProvider(new CachedSecretProvider(provider, configuration)); } } }When accessing the provider in the application, you can use the
ICachedSecretProviderto have access to the cache-specific methods. ex:using Arcus.Security.Core.Caching; namespace Application.Controllers { [ApiController] public class OrderController : ControllerBase { public class OrderController(ICachedSecretProvider secretProvider) { } } }
Contribute your secret provider#
We are open for contributions and are more than happy to receive pull requests with new secret providers!