Peter
Peter

Reputation: 227

Get Key Vault ServiceClient within Program.cs (startup) in a .NET 6 app

I've created an Entity Framework DbContext which I initialize in the Program (Startup.cs is not needed anymore in .NET 6). The connectionstring is dependent on a SQL password inside Azure Key Vault. So the registration of both Key Vault and DbContext are done in the Program.cs . But how do I retrieve the secret from KeyVault to put inside the connectionstring? I do not want to manually create a SecretClient instance here, but have it injected somehow...

I now have:

builder.Services.AddAzureClients(clientBuilder =>
{
    clientBuilder.AddSecretClient(new Uri(builder.Configuration.GetSection("KeyVault:VaultUri").Value))
        .WithCredential(new DefaultAzureCredential());
});
builder.Services.AddDbContext<MyContext>(options =>
{
    // How to get an instance of SecretClient here via DI? I need to call the serviceClient.GetSecret("sql-password") here to put it inside the connectionstring
    // var sqlPassword = builder.Configuration.GetSection("sql-password").Value <-- also returns null
    var sqlPassword = "get-this-password-from-key-vault";
    options.UseSqlServer(string.Format(builder.Configuration.GetConnectionString("MyConnectionString"), sqlPassword));
});

I've read on several blogs that when you add the SecretClient to the Services, it should read all the secrets and add them to the builder.Configuration , meaning you should be able to read it like this:

var sqlPassword = builder.Configuration["sql-password"]

or

var sqlPassword = builder.Configuration.GetSection("sql-password").Value

Both of them return null . So I'm running out of options here. If anyone has a solution for this simple problem, I'm more than grateful. Thanks!

PS: I know for a fact the Key Vault is registered successfully; when I use the ServiceClient within a controller, I can successfully retrieve the secret.

Upvotes: 6

Views: 15853

Answers (1)

Heath
Heath

Reputation: 3292

You can register a SecretClient a number of ways described at https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/extensions/Microsoft.Extensions.Azure/README.md. In this case, you could even instantiate a SecretClient, add it to the configuration builder, then use it directly. Or once registered to the confguration builder, refer to the configuration value you want that is stored in a SecretClient:

var builder = WebApplication.CreateBuilder(args);

var keyVaultEndpoint = new Uri(Environment.GetEnvironmentVariable("VaultUri"));
builder.Configuration.AddAzureKeyVault(keyVaultEndpoint, new DefaultAzureCredential());

// Add services to the container.
builder.Services.AddDbContext<MyContext>(options =>
{
    var sqlPassword = builder.Configuration["secret-password"];
    options.UseSqlite(string.Format(builder.Configuration.GetConnectionString("MyConnectionString"), sqlPassword));
});

In Key Vault, just add a secret named "secret-password" in this case.

Upvotes: 8

Related Questions