Date: 2019-10-09
First you should enable new Authentication Method in Vault web application.
Then you type name. Let’s leave it ‘as is’.
Then you should generate RoleId and SecretId for your application. This values are some kind of login and password for application which allow the application to get an access token. We may use any string. I will generate GUIDs using Online GUID Generator.
Then we write this two GUIDs as RoleId and SecretId in our application.
We use this values to get Vault token for our application.
To use Vault secrets, you should add a provider for reading Auth Token and also a provider for getting keys.
internal class AuthResponse : IAuthResponse
{
public string Accessor { get; }
public string ClientToken { get; }
public bool Renewable { get; }
public int LeaseDuration { get; }
[JsonConstructor]
public AuthResponse(
[JsonProperty("accessor")] string accessor,
[JsonProperty("client_token")] string clientToken,
[JsonProperty("renewable")] bool renewable,
[JsonProperty("lease_duration")] int leaseDuration)
{
Accessor = accessor;
ClientToken = clientToken;
Renewable = renewable;
LeaseDuration = leaseDuration;
}
}
public async Task<IAuthResponse> GetTokenAsync(CancellationToken cancellationToken)
{
// Server Uri and LoginPath you may find in your settings.
var requestUrl = new Uri(new Uri(_config.ServerUri), _config.LoginPath);
var requestPayload = new
{
role_id = _config.AppRoleId, // Role Id (login)
secret_id = _config.AppSecretId // secret Id (password)
};
var request = new HttpRequestMessage(HttpMethod.Post, requestUrl)
{
Content = new ObjectContent<dynamic>(requestPayload, new JsonMediaTypeFormatter())
};
// If you have namespace, you should add it via http headers
if (!string.IsNullOrWhiteSpace(_config.Namespace))
{
request.Headers.Add("X-Vault-Namespace", _config.Namespace);
}
var response = await _httpProvider.SendAsync(request, cancellationToken);
response.EnsureSuccessStatusCode();
var responseJson = await response.Content.ReadAsAsync<JObject>(cancellationToken);
return responseJson["auth"].ToObject<AuthResponse>();
}
Now we have a token that allows us to get secrets from the Vault storage.
// using section start
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Eds.KeyVault.Contracts.Interfaces;
using VaultSharp;
using VaultSharp.V1.AuthMethods.Token;
// using section end
public class KeyVaultSecretClient : IKeyVaultSecretClient
{
// client from VaultSharp namespace.
private readonly IVaultClient _vaultClient;
public KeyVaultSecretClient(IVaultClient vaultClient)
{
_vaultClient = vaultClient ?? throw new ArgumentNullException(nameof(vaultClient));
}
public KeyVaultSecretClient(KeyVaultSecretClientConfig config, string clientToken)
{
if (config == null)
{
throw new ArgumentNullException(nameof(config));
}
var settings = new VaultClientSettings(config.ServerUri, new TokenAuthMethodInfo(clientToken));
if (!string.IsNullOrWhiteSpace(config.Namespace))
{
settings.BeforeApiRequestAction = (httpClient, message) => { message.Headers.Add("X-Vault-Namespace", config.Namespace); };
}
_vaultClient = new VaultClient(settings);
}
public async Task<IDictionary<string, object>> GetSecretsAsync(string secretPath, CancellationToken cancellationToken)
{
var secret = await _vaultClient.V1.Secrets.KeyValue.V1.ReadSecretAsync(secretPath);
return secret.Data;
}
}
Now you may use a dictionary of all key-values from the Vault.
AN official documentation is available here. We are going to add new AppRole record via Vault console.