3

I am trying to setup hashicorp vault and fetch our key value pairs (database credentials) stored in the vault.

I am following below link to connect to vault and fetch credentials from the vault https://github.com/rajanadar/VaultSharp

I can connect and fetch the credentials fine from the vault but my question is how to pass this credentials to my database context. Do I need to store these credentials somewhere, fetch from there and then pass to my DB context or if I need to intialize this class everytime. Below is the sample code for fetching the credentials

public class VaultService : IVaultService 
{   
    public async Task Configure()
    {
       //code to authenticate role and connect vault here 
       
        //Below is the code that actually fetches the credentials. I am just providing relevant code.
        Secret<SecretData> secret = await vaultClient.V1.Secrets.KeyValue.V2.ReadSecretAsync(kvpPath.Value, mountPoint: "kv");
        foreach (var kvp in secret.Data.Data)
        {
            // Console.WriteLine(kvp.Key + " : " + kvp.Value);
        }      
    }   
}   

How can I use the above class to fetch and pass the credentials.

Below is my startup class where my Database context is defined:

public class Startup
{
   public void ConfigureServices(IServiceCollection services)
   {
      services.AddTransient<IDbAdapterService, DbAdapterService>();     
   }
}

Below is my DbAdapterService where I need to use the credentials

public class DbAdapterService : DbAdapterService
{
      private readonly AppSettings _settings;
      public DbAdapterService(IOptions<AppSettings> settings)
      {
           _settings = settings?.Value;
           DbConnectionStringBuilder builder = new DbConnectionStringBuilder();
           //Below is where I need to update the credentials
           builder.ConnectionString = _settings.ConnectionString;           
      }
}
Brenda
  • 510
  • 3
  • 13
  • 36
  • You don't need to overcomplicate it. Use https://github.com/andrewlock/NetEscapades.Configuration#hashicorp-vault-configuration-provider to install an `IConfigurationProvider` for Hashicorp Vault, then configure the dbcontext using `IConfiguration`. – abdusco Jun 30 '21 at 18:54
  • Any inputs to using vault and using the credentials instead of using the method you suggested? – Brenda Jul 04 '21 at 14:46
  • No one for any other inputs? – Brenda Jul 07 '21 at 14:09

3 Answers3

1

I think You are doing great. here is the piece you need.

 builder.ConnectionString = "server=(local);user id=*******;" +
        "password=*******;initial catalog=AdventureWorks";
    builder["Server"] = ".";
//set up individual key with value

Now change class

public class DbAdapterService : DbAdapterService ,IVaultService 


{

 

    private readonly AppSettings _settings;
          public DbAdapterService(IOptions<AppSettings> settings)
          {
               _settings = settings?.Value;
    
    Secret<SecretData> secret = await vaultClient.V1.Secrets.KeyValue.V2.ReadSecretAsync(kvpPath.Value, mountPoint: "kv");
      string Key="";
            foreach (var kvp in secret.Data.Data)
            {
                // Console.WriteLine(kvp.Key + " : " + kvp.Value);
    Key= kvp.Value;
            }   
    
            builder.ConnectionString = "server=(local);user id=*******;" +
                "password=*******;initial catalog=AdventureWorks";
            builder["Server"] = Key;
            builder["User ID"] = Key;
           
    }
    
    }
Jin Thakur
  • 2,711
  • 18
  • 15
0

You can simplify & make things robust quite a bit by following ASP.NET Core's configuration abstractions.

ASP.NET Core provides you IConfiguration and IConfigurationProvider interfaces, which abstracts away where and how the configuration is sourced.

You can use Andrew Lock's configuration provider for Hashicorp Vault, NetEscapades.Configuration.Vault, which will let the app fetch the configuration & secrets from a Vault server.

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((ctx, builder)=> 
        {
            // build the initial config
            var builtConfig = config.Build();

            builder.AddVaultWithAppRole(
                config["VaultUri"], //The Vault uri with port
                config["RoleId"], // The role_id for the app
                config["SecretId"], // The secret_iId for the app
                config["SecretPath"] // secret paths to load
                );
        })
        .UseStartup<Startup>()
        .Build();

then inside the Startup class, you can use IConfiguration and get the connection string to configure the DbContext.

public IConfiguration Configuration { get; set; }
public void ConfigureServices(IServiceCollection services) {
    services.AddDbContext<AppDbContext>(o => 
        o.UseSqlServer(Configuration.GetConnectionString("SqlServer"))
    );
}

References:

abdusco
  • 9,700
  • 2
  • 27
  • 44
  • Thanks for this. We are using aws role here, so the first step is to authenticate via role.The role is also attached to the role to connect and fetch the details. So I am not sure how will that fit here. Also we just have the aws role, the vault uri and secret path, dont know what secret id here is. Can you share if I go with my logic as I mentioned in my post what changes do I have to do, and what options do I have if I use vaultsharp. Thanks – Brenda Jul 01 '21 at 17:47
0

I think the easiest way is to use any of the libraries developed for that purpose by the community:

https://github.com/stratio-automotive/Stratio.Extensions.Configuration.Vault

https://github.com/andrewlock/NetEscapades.Configuration#hashicorp-vault-configuration-provider

https://github.com/MrZoidberg/VaultSharp.Extensions.Configuration

Personally, I think that Stratio's library is more flexible than Zoidberg's, although Zoidberg's is more complete with the hot reload feature. I've never tried NetEscapades library. Hot reload is planned on Stratio's library.

Full disclosure: I am one of the maintainers of Stratio's Configuration Extension Vault library