DEV Community

Cover image for Google Secret Manager Configuration Provider for ASP.NET Core
Igor Bertnyk
Igor Bertnyk

Posted on • Updated on

Google Secret Manager Configuration Provider for ASP.NET Core

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();
        }
    }
Enter fullscreen mode Exit fullscreen mode

SecretManagerConfigurationProvider

Next, let's start creating our main component, SecretManagerConfigurationProvider, which needs to inherit from the ConfigurationProvider abstract class:

public class SecretManagerConfigurationProvider : ConfigurationProvider
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

Returning to our Configuration Provider, we are ready to initialize it in the constructor:

public SecretManagerConfigurationProvider()
{
    _client = SecretManagerServiceClient.Create();
    _projectId = GoogleProject.GetProjectId();
}
Enter fullscreen mode Exit fullscreen mode

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());
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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>());
Enter fullscreen mode Exit fullscreen mode

The full source code of Google Secret Manager Configuration Provider, with more error handling, comments, and tests can be found in this Github repo:

GitHub logo 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.

cat hacker(Image credit: iridi/Getty Images)

Discussion (0)