/// <summary> /// if Azure Key Value is available, reads configuration values from the Azure KeyVault. /// </summary> /// <param name="builder"><see cref="IConfigurationBuilder"/></param> public static IConfigurationBuilder AddAzureKeyVaultIfAvailable(this IConfigurationBuilder builder) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } var configurationRoot = builder.Build(); var keyVaultConfiguration = configurationRoot.GetSection(AzureKeyVaultKey); string clientId = keyVaultConfiguration["ClientId"]; string vaultUrl = keyVaultConfiguration[AzureKeyVaultUrlKey]; if (string.IsNullOrEmpty(vaultUrl)) { return(builder); } if (string.IsNullOrWhiteSpace(clientId)) { // Try to access the Key Vault utilizing the Managed Service Identity of the running resource/process builder.AddAzureKeyVault(vaultUrl, AzureKeyVaultHelper.GetKeyVaultClientFromManagedIdentity(), new DefaultKeyVaultSecretManager()); } else { // Allow to override the MSI or for local dev builder.AddAzureKeyVault(vaultUrl, clientId, keyVaultConfiguration["ClientSecret"]); } return(builder); }
static void ConfigConfiguration(HostBuilderContext hostBuilderContext, IConfigurationBuilder configurationBuilder) { ////if (hostBuilderContext.HostingEnvironment.IsProduction()) ////{ var builtConfig = configurationBuilder .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", false, true) .AddEnvironmentVariables() .Build(); if (!string.IsNullOrEmpty(builtConfig["azureKeyVault:KeyVaultName"])) { var keyVaultAddress = $"https://{builtConfig["azureKeyVault:KeyVaultName"]}.vault.azure.net/"; if (!string.IsNullOrEmpty(keyVaultAddress)) { configurationBuilder.AddAzureKeyVault(keyVaultAddress, InitKeyVault(keyVaultAddress, builtConfig["azureKeyVault:ClientId"], builtConfig["azureKeyVault:ClientSecret"]), new DefaultKeyVaultSecretManager()); } } if (!string.IsNullOrEmpty(builtConfig["azureKeyVault:Core:KeyVaultName"])) { var keyCoreVaultAddress = $"https://{builtConfig["azureKeyVault:Core:KeyVaultName"]}.vault.azure.net/"; configurationBuilder.AddAzureKeyVault(keyCoreVaultAddress, InitKeyVault(keyCoreVaultAddress, builtConfig["azureKeyVault:Core:ClientId"], builtConfig["azureKeyVault:Core:ClientSecret"]), new DefaultKeyVaultSecretManager()); } //} }
public static IConfigurationBuilder AddAzureKeyVault(this IConfigurationBuilder builder) { var builtConfig = builder.Build(); var keyVaultName = builtConfig["KeyVaultName"]; if (!string.IsNullOrWhiteSpace(keyVaultName)) { var userAssignedClientId = builtConfig["UserAssignedClientId"]; var credentials = string.IsNullOrWhiteSpace(userAssignedClientId) ? new DefaultAzureCredential() : new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = userAssignedClientId }); builder.AddAzureKeyVault(new Uri($"https://{keyVaultName}.vault.azure.net/"), credentials); } else { // docker-compose local mode var mountedVolume = builtConfig["KeyVault:Path"]; if (!string.IsNullOrWhiteSpace(mountedVolume)) { keyVaultName = File.ReadAllText($"{mountedVolume}/keyVaultName"); var tenantId = File.ReadAllText($"{mountedVolume}/tenantId"); var clientId = File.ReadAllText($"{mountedVolume}/clientId"); var secret = File.ReadAllText($"{mountedVolume}/clientSecret"); var credentials = new ClientSecretCredential(tenantId, clientId, secret); builder.AddAzureKeyVault(new Uri($"https://{keyVaultName}.vault.azure.net/"), credentials); } } return(builder); }
/// <summary> /// Add Azure KeyVault using Managed identity. /// </summary> /// <param name="configBuilder">config builder</param> /// <returns>config builder</returns> private static IConfigurationBuilder TryAddAzureKeyVault(this IConfigurationBuilder configBuilder) { if (configBuilder == null) { throw new ArgumentNullException(nameof(configBuilder)); } if (!string.IsNullOrWhiteSpace(KeyVaultName)) { if (IsDevelopment) { // Add Azure keyvault with app id and app secret from user secrets var tempConfig = configBuilder.Build(); var clientId = tempConfig[UserSecrets_KeyVaultAppIdKey]; var clientSecret = tempConfig[UserSecrets_KeyVaultAppSecretKey]; configBuilder.AddAzureKeyVault(KeyVaultUrl, clientId, clientSecret); } else { // Non-development environment. Add keyvault from managed identity var azureServiceTokenProvider = new AzureServiceTokenProvider(); var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)); configBuilder.AddAzureKeyVault(KeyVaultUrl, keyVaultClient, new DefaultKeyVaultSecretManager()); } } return(configBuilder); }
public static void AddAzureKeyVaultConfiguration(this IConfiguration configuration, IConfigurationBuilder configurationBuilder) { if (configuration.GetSection(nameof(AzureKeyVaultConfiguration)).Exists()) { var azureKeyVaultConfiguration = configuration.GetSection(nameof(AzureKeyVaultConfiguration)).Get <AzureKeyVaultConfiguration>(); if (azureKeyVaultConfiguration.ReadConfigurationFromKeyVault) { if (azureKeyVaultConfiguration.UseClientCredentials) { configurationBuilder.AddAzureKeyVault(azureKeyVaultConfiguration.AzureKeyVaultEndpoint, azureKeyVaultConfiguration.ClientId, azureKeyVaultConfiguration.ClientSecret); } else { var keyVaultClient = new KeyVaultClient( new KeyVaultClient.AuthenticationCallback(new AzureServiceTokenProvider() .KeyVaultTokenCallback)); configurationBuilder.AddAzureKeyVault(azureKeyVaultConfiguration.AzureKeyVaultEndpoint, keyVaultClient, new DefaultKeyVaultSecretManager()); } } } }
/// <summary> /// Adds Azure Key Vaults with VS.NET or MSI authentication only. /// </summary> /// <param name="builder">The <see cref="IConfigurationBuilder"/> configuration builder instance.</param> /// <param name="keyVaultEndpoints">The default Azure Key Vaults values separated by ';'.</param> /// <param name="usePrefix">The default is true. It adds prefixed values from the vault.</param> /// <param name="hostingEnviromentName">The hosting environment that is matched to 'dev, stage or prod'.</param> /// <returns></returns> public static IConfigurationRoot AddAzureKeyVaults( this IConfigurationBuilder builder, string keyVaultEndpoints, bool usePrefix = true, string hostingEnviromentName = null) { if (!string.IsNullOrEmpty(keyVaultEndpoints)) { var prefix = string.Empty; if (usePrefix) { Enviroments.TryGetValue(hostingEnviromentName, out prefix); } foreach (var splitEndpoint in keyVaultEndpoints.Split(';')) { var azureServiceTokenProvider = new AzureServiceTokenProvider(); var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)); builder.AddAzureKeyVault(splitEndpoint, keyVaultClient, new PrefixExcludingKeyVaultSecretManager()); if (!string.IsNullOrEmpty(prefix)) { builder.AddAzureKeyVault(splitEndpoint, keyVaultClient, new PrefixKeyVaultSecretManager(prefix)); } } } return(builder.Build()); }
private static void ConfigureAppConfiguration(WebHostBuilderContext context, IConfigurationBuilder config) { // https://docs.microsoft.com/en-us/aspnet/core/security/key-vault-configuration // https://docs.microsoft.com/en-us/aspnet/core/security/app-secrets if (!context.HostingEnvironment.IsDevelopment()) { // TODO (vladcananau): bad practice to build the config here // https://github.com/aspnet/Docs/issues/11616 // Ideally we would want the AddAzureKeyVault to grab a well known // KeyVault configuration section; var builtConfig = config.Build(); string keyVaultEndpoint = builtConfig["KeyVault:Endpoint"]; var azureServiceTokenProvider = new AzureServiceTokenProvider(); var keyVaultClient = new KeyVaultClient( new KeyVaultClient.AuthenticationCallback( azureServiceTokenProvider.KeyVaultTokenCallback)); config.AddAzureKeyVault( keyVaultEndpoint, keyVaultClient, new DefaultKeyVaultSecretManager()); } }
public static IConfigurationBuilder AddAzureKeyVault(this IConfigurationBuilder builder, Action <KeyVaultOptions> configure = null) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } var config = builder.Build(); var options = new KeyVaultOptions(); config.GetSection(nameof(KeyVaultOptions)).Bind(options); configure?.Invoke(options); if (!options.KeyVaultNames.Any()) { return(builder); } using var store = new X509Store(options.LocalCertificateStore); store.Open(OpenFlags.ReadOnly); var certs = store.Certificates.Find( X509FindType.FindByThumbprint, config[options.AzureAdApplicationCertThumbprint], false); foreach (var keyVaultName in options.KeyVaultNames) { builder.AddAzureKeyVault(new Uri($"https://{keyVaultName}.vault.azure.net/"), new ClientCertificateCredential(options.AzureAdTenantId, options.AzureAdApplicationId, certs.OfType <X509Certificate2>().Single()), new KeyVaultSecretManager()); } store.Close(); return(builder); }
private void AddKeyVault(IConfigurationBuilder builder) { var baseConfig = builder //.AddEnvironmentVariables() .Build(); var thumbprint = baseConfig["AAD:Thumbprint"]; if (!string.IsNullOrEmpty(thumbprint)) { var cert = CertificateLoader.GetCertificate(thumbprint); if (cert != null) { builder.AddAzureKeyVault( baseConfig["Vault:Name"], baseConfig["AAD:AppId"], cert, new SecretManager()); } else { //log it! } } }
/// <summary> /// Tries to configure Azure Key Vault. /// </summary> /// <param name="builder">The current <see cref="IConfigurationBuilder"/>.</param> /// <returns> /// The <see cref="IConfigurationRoot"/> to use for the application. /// </returns> private static IConfigurationRoot TryConfigureAzureKeyVault(IConfigurationBuilder builder) { // Build the main configuration IConfigurationRoot config = builder.Build(); // Get the settings for Azure Key Vault string vault = config["AzureKeyVault:Uri"]; string clientId = config["AzureKeyVault:ClientId"]; string clientSecret = config["AzureKeyVault:ClientSecret"]; bool canUseKeyVault = !string.IsNullOrEmpty(vault) && !string.IsNullOrEmpty(clientId) && !string.IsNullOrEmpty(clientSecret); if (canUseKeyVault) { // Add Azure Key Vault and replace the configuration built already var manager = new AzureEnvironmentSecretManager(config.AzureEnvironment()); builder.AddAzureKeyVault( vault, clientId, clientSecret, manager); config = builder.Build(); } return(config); }
/// <summary> /// Adds an <see cref="IConfigurationProvider"/> that reads configuration values from the Azure KeyVault. /// </summary> /// <param name="configBuilder">The <see cref="IConfigurationBuilder"/> to add to.</param> /// <param name="options">Delegate to configure key vault options. The options are preconfigured with values /// from section <c>KeyVault</c> in <c>appsettings.json</c> configuration.</param> /// <returns>The <see cref="IConfigurationBuilder"/>.</returns> public static IConfigurationBuilder AddAzureKeyVault( this IConfigurationBuilder configBuilder, Action <KeyVaultOptions> options = null) { IConfigurationRoot settings = configBuilder.Build(); KeyVaultOptions kvOptions = new(); settings.Bind("KeyVault", kvOptions); options?.Invoke(kvOptions); if (string.IsNullOrWhiteSpace(kvOptions.Name)) { return(configBuilder); } DefaultAzureCredential credential = CreateAzureCredential(kvOptions.IdentityClientId); AzureKeyVaultConfigurationOptions kvConfigOptions = new() { Manager = kvOptions.Prefixes.Count == 0 ? new KeyVaultSecretManager() : new PrefixKeyVaultSecretManager(kvOptions.Prefixes), ReloadInterval = kvOptions.ReloadInterval > default(TimeSpan) ? kvOptions.ReloadInterval : null }; configBuilder.AddAzureKeyVault(new Uri($"https://{kvOptions.Name}.vault.azure.net/"), credential, kvConfigOptions); return(configBuilder); }
public static IConfigurationBuilder SetupKeyVault(this IConfigurationBuilder builder, ILogger logger) { var configuration = builder.Build(); var keyVaultURL = configuration["KeyVault:URL"]; var appId = configuration["AzureAD:AppId"]; // key vault access using certificate (private/public key) using (var store = new X509Store(StoreName.My, StoreLocation.LocalMachine)) { store.Open(OpenFlags.ReadOnly); var certs = store.Certificates; logger.LogDebug("Num of certificates in store: " + certs.Count); var distinguishedName = new X500DistinguishedName(configuration["KeyVault:SubjectDistinguishedName"]); var certFound = certs.Find(X509FindType.FindBySubjectDistinguishedName, distinguishedName.Name, false).OfType <X509Certificate2>(); if (!certFound.Any()) { logger.LogWarning("Unable to find the certificate to authenticate and access key vault"); } else { // found the certificate builder.AddAzureKeyVault(keyVaultURL, appId, certFound.Single()); store.Close(); } } return(builder); }
private static IConfiguration BuildAppConfiguration(IConfigurationBuilder builder, WebHostBuilderContext hostingContext) { var environment = hostingContext.HostingEnvironment; IConfiguration configuration = builder.Build(); if (environment.IsDevelopment()) { builder.AddUserSecrets(Assembly.Load(new AssemblyName(environment.ApplicationName)), optional: true); } // TODO : Work out why the instrumentation key below is ignored, the correct instrumentation key seems to be only // set if it is present in the appsettings.json or is passed to the overloaded extensions method on IWebHostBuilder called UseApplicationInsights. var applicationInsightsSettings = new ApplicationInsightsSettings(); configuration.BindOrThrow("ApplicationInsights", applicationInsightsSettings); builder.AddApplicationInsightsSettings(developerMode: environment.IsDevelopment(), instrumentationKey: applicationInsightsSettings.InstrumentationKey); KeyVaultSettings keyVaultSettings = new KeyVaultSettings(); configuration.BindOrThrow("KeyVaultSettings", keyVaultSettings); builder.AddAzureKeyVault( keyVaultSettings.DnsName, keyVaultSettings.AppUserClientId, keyVaultSettings.AppUserClientSecret); return(configuration); }
public static IConfigurationBuilder ConfigureKeyVault(this IConfigurationBuilder config) => config.AddAzureKeyVault( Environment.GetEnvironmentVariable(Vault), new KeyVaultClient( new KeyVaultClient.AuthenticationCallback( new AzureServiceTokenProvider().KeyVaultTokenCallback)), new DefaultKeyVaultSecretManager());
private void LoadAkvConfig( ref IConfiguration config, ref IConfigurationBuilder configBuilder) { string akvName = config[$"{CommonConstants.AzureKeyVaultSetts}:{CommonConstants.AzureKeyVaultSettsVaultName}"]; if (string.IsNullOrEmpty(akvName)) { throw new NullReferenceException( message: CommonConstants.MessageKeyVaultNameCannotBeNull); } string akvClientId = config[$"{CommonConstants.AzureKeyVaultSetts}:{CommonConstants.AzureKeyVaultSettsVaultClientId}"]; if (string.IsNullOrEmpty(akvClientId)) { throw new NullReferenceException( message: CommonConstants.MessageKeyVaultClientIdCannotBeNull); } string akvClientSecret = config[$"{CommonConstants.AzureKeyVaultSetts}:{CommonConstants.AzureKeyVaultSettsVaultSecret}"]; if (string.IsNullOrEmpty(akvClientSecret)) { throw new NullReferenceException( message: CommonConstants.MessageKeyVaultClientSecretCannotBeNull); } // Add the Azure Key Vault configBuilder.AddAzureKeyVault(vault: $"https://{akvName}.vault.azure.net/", clientId: akvClientId, clientSecret: akvClientSecret); // Build the configuration config = configBuilder.Build(); }
public static IConfigurationBuilder BuildAppConfiguration(WebHostBuilderContext context, IConfigurationBuilder configBuilder, string[] args) { configBuilder.SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", true, true) .AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", true, true) .AddCommandLine(args) .AddEnvironmentVariables(); if (context.HostingEnvironment.IsDevelopment()) { configBuilder.AddUserSecrets <Startup>(); } IConfigurationRoot built = configBuilder.Build(); if (!built .GetSection("keyVault") .Exists()) { return(configBuilder); } try { var azureServiceTokenProvider = new AzureServiceTokenProvider(); var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)); configBuilder.AddAzureKeyVault($"https://{built["AzureKeyVault:Name"]}.vault.azure.net/", keyVaultClient, new PrefixKeyVaultSecretManager(built["AzureKeyVault:Prefix"])); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } return(configBuilder); }
static void ConfigConfiguration(WebHostBuilderContext webHostBuilderContext, IConfigurationBuilder configurationBuilder) { configurationBuilder.SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", false, true) .AddEnvironmentVariables(); var config = configurationBuilder.Build(); if (webHostBuilderContext.HostingEnvironment.IsDevelopment()) { configurationBuilder.AddUserSecrets <Startup>(); } else if (webHostBuilderContext.HostingEnvironment.IsProduction()) { string keyVault = Environment.GetEnvironmentVariable("APP_AZUREKEYVAULT_NAME"); string clientId = Environment.GetEnvironmentVariable("APP_AZUREKEYVAULT_CLIENTID"); string clientSecret = Environment.GetEnvironmentVariable("APP_AZUREKEYVAULT_CLIENTSECRET"); configurationBuilder.AddAzureKeyVault( $"https://{keyVault}.vault.azure.net/", clientId, clientSecret ); } }
/// <summary> /// Adds Azure Key Vaults with VS.NET or MSI authentication only. /// </summary> /// <param name="builder">The <see cref="IConfigurationBuilder"/> configuration builder instance.</param> /// <param name="keyVaultEndpoints">The default Azure Key Vaults values separated by ';'.</param> /// <param name="usePrefix">The default is true. It adds prefixed values from the vault.</param> /// <param name="hostingEnviromentName">The hosting environment that is matched to 'dev, stage or prod'.</param> /// <param name="reloadInterval">The reload interval for the Azure Key Vault.</param> /// <param name="enviroments">The conversion for HostEnvironment:Prefix. The default is null.</param> /// <returns></returns> public static IConfigurationRoot AddAzureKeyVaults( this IConfigurationBuilder builder, string keyVaultEndpoints, bool usePrefix = true, string?hostingEnviromentName = null, TimeSpan?reloadInterval = null, Environments?enviroments = null) { if (!string.IsNullOrEmpty(keyVaultEndpoints)) { enviroments ??= new Environments(); var prefix = string.Empty; if (usePrefix && hostingEnviromentName != null) { enviroments.TryGetValue(hostingEnviromentName, out prefix); } var azureServiceTokenProvider = new AzureServiceTokenProvider(); #pragma warning disable CA2000 // Dispose objects before losing scope var keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback)); #pragma warning restore CA2000 // Dispose objects before losing scope foreach (var splitEndpoint in keyVaultEndpoints.Split(';')) { builder.AddAzureKeyVault(new AzureKeyVaultConfigurationOptions(splitEndpoint) { Client = keyVaultClient, Manager = new PrefixExcludingKeyVaultSecretManager(enviroments), ReloadInterval = reloadInterval }); if (!string.IsNullOrEmpty(prefix)) { builder.AddAzureKeyVault(new AzureKeyVaultConfigurationOptions(splitEndpoint) { Client = keyVaultClient, Manager = new PrefixKeyVaultSecretManager(prefix), ReloadInterval = reloadInterval }); } } } return(builder.Build()); }
public static IConfigurationBuilder AddSecrets(this IConfigurationBuilder configurationBuilder) { var keyVaultUri = Environment.GetEnvironmentVariable("KeyVaultUri"); return(!string.IsNullOrWhiteSpace(keyVaultUri) ? configurationBuilder.AddAzureKeyVault(keyVaultUri) : configurationBuilder); }
/// <summary> /// Adds an <see cref="IConfigurationProvider"/> that reads configuration values from the Azure KeyVault. /// </summary> /// <param name="configurationBuilder">The <see cref="IConfigurationBuilder"/> to add to.</param> /// <param name="vaultUri">Azure Key Vault uri.</param> /// <param name="credential">The credential to to use for authentication.</param> /// <param name="options">The <see cref="AzureKvConfigurationOptions"/> to use.</param> /// <returns>The <see cref="IConfigurationBuilder"/>.</returns> public static IConfigurationBuilder AddAzureKeyVault( this IConfigurationBuilder configurationBuilder, Uri vaultUri, TokenCredential credential, AzureKvConfigurationOptions options) { return(configurationBuilder.AddAzureKeyVault(new SecretClient(vaultUri, credential), options)); }
/// <summary> /// Configures the application. /// </summary> /// <param name="builder">The <see cref="IConfigurationBuilder"/> to configure.</param> /// <param name="context">The <see cref="HostBuilderContext"/> to use.</param> /// <returns> /// The <see cref="IConfigurationBuilder"/> passed as the value of <paramref name="builder"/>. /// </returns> public static IConfigurationBuilder ConfigureApplication(this IConfigurationBuilder builder, HostBuilderContext context) { builder.AddApplicationInsightsSettings(developerMode: context.HostingEnvironment.IsDevelopment()); // Build the configuration so far IConfiguration config = builder.Build(); // Get the settings for Azure Key Vault string vault = config["AzureKeyVault:Uri"]; string clientId = config["AzureKeyVault:ClientId"]; string clientSecret = config["AzureKeyVault:ClientSecret"]; // Can Managed Service Identity be used instead of direct Key Vault integration? bool canUseMsi = !string.Equals(config["WEBSITE_DISABLE_MSI"], bool.TrueString, StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(config["MSI_ENDPOINT"]) && !string.IsNullOrEmpty(config["MSI_SECRET"]); bool canUseKeyVault = !string.IsNullOrEmpty(vault) && (canUseMsi || (!string.IsNullOrEmpty(clientId) && !string.IsNullOrEmpty(clientSecret))); if (canUseKeyVault) { var manager = new AzureEnvironmentSecretManager(config.AzureEnvironment()); if (canUseMsi) { #pragma warning disable CA2000 var provider = new AzureServiceTokenProvider(); var client = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(provider.KeyVaultTokenCallback)); builder.AddAzureKeyVault(vault, client, manager); #pragma warning restore CA2000 } else { builder.AddAzureKeyVault( vault, clientId, clientSecret, manager); } } return(builder); }
/// <summary> /// Adds an <see cref="IConfigurationProvider"/> that reads configuration values from the Azure KeyVault. /// </summary> /// <param name="configurationBuilder">The <see cref="IConfigurationBuilder"/> to add to.</param> /// <param name="client">The <see cref="SecretClient"/> to use for retrieving values.</param> /// <param name="options">The <see cref="AzureKvConfigurationOptions"/> to use.</param> /// <returns>The <see cref="IConfigurationBuilder"/>.</returns> public static IConfigurationBuilder AddAzureKeyVault( this IConfigurationBuilder configurationBuilder, SecretClient client, AzureKvConfigurationOptions options) { options.Client = client; return(configurationBuilder.AddAzureKeyVault(options)); }
private IConfigurationBuilder ConfigureAzureKeyVaultConfigUsingSecret(IConfigurationBuilder builder, CodePackageActivationContext activationContext, string keyVaultUri, string clientId) { var clientSecret = activationContext.GetSetting(new SettingKey <string>("Config", "Azure", "ClientSecret")); Args.NotNullOrEmpty(clientSecret, "ClientSecret", "No ClientSecret was provided for KeyVault authorization"); return(builder.AddAzureKeyVault(keyVaultUri, clientId, clientSecret)); }