Google Secret Manager Configuration Provider for ASP.NET Core
Igor Bertnyk
Posted on August 18, 2021
If you are brave enough to run ASP.NET Core applications on Google Cloud Platform, sooner or later you will encounter a question on how to store your application settings in a secure way. In Azure we have Key Vault for that purpose, which is nicely integrated with ASP.NET Core thanks to the built-in Configuration Provider. In GCP, the corresponding service is called Google Secret Manager.
Secret Manager is a secure and convenient storage system for API keys, passwords, certificates, and other sensitive data, and certainly is a good place to store application settings as well. However there is no integration with ASP.NET Core out of the box.
Fear not! ASP.NET Core supports Custom configuration providers, and we will try to develop one for the Google Secret Manager now.
SecretManagerConfigurationSource
First of all, we need to create a class that implements IConfigurationSource. The only purpose of which is to return an instance of our custom provider, which we develop shortly.
public class SecretManagerConfigurationSource : IConfigurationSource
{
public IConfigurationProvider Build(IConfigurationBuilder builder)
{
return new SecretManagerConfigurationProvider();
}
}
SecretManagerConfigurationProvider
Next, let's start creating our main component, SecretManagerConfigurationProvider, which needs to inherit from the ConfigurationProvider abstract class:
public class SecretManagerConfigurationProvider : ConfigurationProvider
To retrieve secrets from the Secret Manager, we can use SecretManagerServiceClient from Google.Cloud.SecretManager.V1 Nuget package. We will also need a Google Project ID where the Secret Manager is enabled and your application is running.
How can we get a Project ID? We can, for example, put it into applications settings. But in fact, we can get it easily at runtime using Google API:
public static string GetProjectId()
{
var instance = Google.Api.Gax.Platform.Instance();
var projectId = instance?.ProjectId;
if (string.IsNullOrEmpty(projectId))
{
return null;
}
return projectId;
}
Returning to our Configuration Provider, we are ready to initialize it in the constructor:
public SecretManagerConfigurationProvider()
{
_client = SecretManagerServiceClient.Create();
_projectId = GoogleProject.GetProjectId();
}
The next step is to overload the "Load" method and populate a Dictionary of key/value pairs that is exposed as Data property in the parent class.
var secrets = _client.ListSecrets(new ProjectName(_projectId));
foreach (var secret in secrets)
{
var secretVersionName = new SecretVersionName(secret.SecretName.ProjectId, secret.SecretName.SecretId, "latest");
var secretVersion = _client.AccessSecretVersion(secretVersionName);
Set(secret.SecretName.SecretId, secretVersion.Payload.Data.ToStringUtf8());
}
SecretManagerConfigurationExtensions
Finally, let's add a convenience extension method to easily add our new configuration provider to the ASP.NET Core application.
public static IConfigurationBuilder AddGoogleSecretsManager(this IConfigurationBuilder configurationBuilder)
{
configurationBuilder.Add(new SecretManagerConfigurationSource());
return configurationBuilder;
}
Typically, you'd use this method in Program.cs file:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((_, config) => config.AddGoogleSecretsManager())
.ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>());
The full source code of Google Secret Manager Configuration Provider, with more error handling, comments, and tests can be found in this Github repo:
i-b1 / GoogleSecretManagerConfigurationProvider
Google Secret Manager Configuration Provider
More than that, you can download a IB.Google.SecretManager.ConfigurationProvider NuGet package and use freely in your projects
And that is essentially everything that was needed to implement a custom configuration provider. Now you can start using Google Secret Manager to store your applications settings in a more secure way, simplify your CD pipelines by removing those variables from different stages, and stop worrying about those pesky cat hackers.
Posted on August 18, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.