HashiCorp.Vault
0.3.0
Prefix Reserved
dotnet add package HashiCorp.Vault --version 0.3.0
NuGet\Install-Package HashiCorp.Vault -Version 0.3.0
<PackageReference Include="HashiCorp.Vault" Version="0.3.0" />
paket add HashiCorp.Vault --version 0.3.0
#r "nuget: HashiCorp.Vault, 0.3.0"
// Install HashiCorp.Vault as a Cake Addin #addin nuget:?package=HashiCorp.Vault&version=0.3.0 // Install HashiCorp.Vault as a Cake Tool #tool nuget:?package=HashiCorp.Vault&version=0.3.0
Vault .NET Client Library
A .NET client library generated from OpenAPI
specification file to interact with Hashicorp
Vault.
Note: This library is currently marked as BETA. Please try it out and give us feedback! Please do not use it in production.
Note: We take Vault's security and our users' trust very seriously. If you believe you have found a security issue in Vault .NET, please responsibly disclose by contacting us at security@hashicorp.com.
Contents
- Vault .NET Client Library
Installation
Vault is a package available at Hashicorp Nuget. We've provided install commands below.
Using Powershell:
Install-Package HashiCorp.Vault -Version "0.2.0"
Using Nuget CLI:
nuget install HashiCorp.Vault -Version "0.2.0"
Note: You can find the latest package version in the Release tab in GitHub.
You can add the package to your .Net project using the following command:
dotnet add package Hashicorp.Vault -version "0.2.0"
Frameworks supported
- .NET Core >=1.0
- .NET Framework >=4.6
- Mono/Xamarin >=vNext
Examples
Getting Started
Here is a simple copy-pastable example of using the library to write a secret to
the kv secrets engine and then read the secret back. This example works with a
Vault server started in dev mode with a hardcoded root token (e.g.
vault server -dev -dev-root-token-id="my-token"
);
using Vault;
using Vault.Client;
using Vault.Model;
namespace Example
{
public class Example
{
public static void Main()
{
string address = "http://127.0.0.1:8200";
VaultConfiguration config = new VaultConfiguration(address);
VaultClient vaultClient = new VaultClient(config);
vaultClient.SetToken("my-token");
try
{
var secretData = new Dictionary<string, string> { { "mypass", "pass" } };
// Write a secret
var kvRequestData = new KvV2WriteRequest(secretData);
vaultClient.Secrets.KvV2Write("mypath", kvRequestData);
// Read a secret
VaultResponse<KvV2ReadResponse> resp = vaultClient.Secrets.KvV2Read("mypath");
Console.WriteLine(resp.Data.Data);
}
catch (VaultApiException e)
{
Console.WriteLine("Failed to read secret with message {0}", e.Message);
}
}
}
}
Note: the responses are currently generic objects that need to be marshalled into an appropriate model. Structured responses are coming soon!
Configuring a Vault Client
The VaultClient requires you pass it a VaultConfiguration
object.
VaultConfiguration config = new VaultConfiguration("http:127.0.0.1:8200");
VaultClient vaultClient = new VaultClient(config);
You can also add custom configuration including a custom HttpClientHandler
.
This can be used to intercept requests and add custom logic before the base
SendAsync
is called by the HttpClient. See HttpClientHandler
docs for more details.
// Create a custom HttpClientHandler
HttpClientHandler myClientHandler = new HttpClientHandler();
VaultConfiguration config = new VaultConfiguration("http://127.0.0.1:8200",
myClientHandler);
The VaultClient also allows you to set a custom Timeout for all API calls.
VaultConfiguration config = new VaultConfiguration(basePath: address,
httpClientHandler: httpClientHandler,
timeout: TimeSpan.FromSeconds(15));
Setting Headers
The SetToken
method can be used to set the X-Vault-Token
header with the
given token for subsequent requests.
vaultClient.SetToken("my-token");
The SetNamespace
can be used to set the default namespace header.
vaultClient.SetNamespace("n1");
vaultClient.ClearNamespace();
The Vault client also allows for adding custom headers that will be applied to every request.
IDictionary<string, string> myCustomHeaders = new Dictionary<string, string>
{
{ "my-custom-header", "myHeaders"}
};
vaultClient.AddCustomHeaders(myCustomHeaders);
vaultClient.ClearCustomHeaders();
Authenticating with Vault
In the previous example we used an insecure (root token) authentication method.
For production applications, it is recommended to use approle or
one of the platform-specific authentication methods instead (e.g.
kubernetes, AWS, Azure, etc.). The
functions to access these authentication methods are automatically generated
under vaultClient.Auth
. Below is an example of how to authenticate using
approle
authentication method. Please refer to the approle
documentation for more details.
VaultResponse<Object> resp = vaultClient.Auth.AppRoleLogin(
new AppRoleLoginRequest(roleId: "myRoleId", secretId: "mySecretId"),
approleMountPath: "my/mount/path");
vaultClient.SetToken(token: resp.ResponseAuth.ClientToken);
The secret identifier is often delivered as a wrapped token. In this case, you should unwrap it first as demonstrated here.
Reading a KV Secret
To call secrets endpoints, simply use the VaultClient.Secrets
object, as shown
below.
All secrets and auth calls have an optional mount path parameter that can be specified, otherwise we will use a default mount path.
VaultResponse<KvV2ReadResponse> resp = await vaultClient.Secrets.KvV2ReadAsync("path", secretMountPath: "myCustomMountPath");
Console.WriteLine(resp.Data);
All calls have both an async and synchronous implementation. E.g.
VaultResponse<KvV2ReadResponse> respAsync = await vaultClient.Secrets.KvV2ReadAsync("path");
VaultResponse<KvV2ReadResponse> respSync = vaultClient.Secrets.KvV2ReadAsync("path");
Exception Handling
For api level exceptions we provide the VaultApiException
that provides the
Vault specific errors, status code and original error content.
try
{
// Example call to Vault
vaultClient.System.MountsListSecretsEngines();
}
catch (VaultApiException e)
{
// Status Code
Console.WriteLine("Status code: {0}", e.StatusCode);
// Print the individual errors returned by Vault
e.Errors.ToList().ForEach(x => Console.WriteLine(x));
// Well formatted exception message
Console.WriteLine(e.Message);
}
Wrapping and Unwrapping Responses
All functions accept an optional TimeSpan? wrapTTL
function parameter. Vault
will wrap the response and return a response-wrapping token instead. More
documentation on response wrapping can be found here.
// Get a wrapped response from Vault
VaultResponse<Object> wrappedResp = vaultClient.System.MountsListSecretsEngines(wrapTTL: TimeSpan.FromSeconds(100));
// Unwrap the given response object
VaultResponse<Object> unwrappedResp = vaultClient.Unwrap<Object>(wrappedResp.ResponseWrapInfo.Token);
We also provide an async version.
Task<VaultResponse<Object>> unwrappedResp = await vauClient.UnwrapAsync<Object>(wrappedResp.ResponseWrapInfo.Token);
Performing Generic Operations
We provide generic accessors for Read
, Write
, List
and Delete
, should
you need to access an endpoint that is not available in the library (e.g. a
plugin that is not builtin to Vault).
Each generic operation has a synchronous and asynchronous version.
// Generic read from a path with query parameters
var readPath = "/some/path"
IDictionary<string, object> queryParams = new Dictionary<string, object>
{
{"key", "value"}
};
VaultResponse<Object> resp = await vaultClient.ReadAsync<Object>(myPath, queryParams);
// Generic write to a path
var writePath = "/some/other/path";
IDictionary<string, object> secretData = new Dictionary<string, object>
{
{"1", "1"},
{"2", 2},
{"3", false},
};
await vaultClient.WriteAsync<Object>(writePath, secretData);
Contributing to Vault .Net Library
Local Development
To develop locally with the Vault .Net Library, you can generate the DLL using
your preferred tool (e.g. dotnet build
) in the src
folder.
Then include the generated DLL (under the bin
folder) in the C# project, and
use the namespaces:
using Vault;
using Vault.Api;
using Vault.Client;
using Vault.Model;
You will also need to include the following dependencies:
Using your preferred method:
Install-Package Newtonsoft.Json
Install-Package Polly
Documentation for API Endpoints
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- JsonSubTypes (>= 2.0.1)
- Newtonsoft.Json (>= 13.0.3)
- Polly (>= 7.2.4)
- System.ComponentModel.Annotations (>= 5.0.0)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on HashiCorp.Vault:
Package | Downloads |
---|---|
LvmServers.ScoreBoardPlugin
Package Description |
|
LvmServers.ChatDesignerPlugin
Package Description |
|
LvmServers.Services
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
0.3.0 | 87,507 | 8/31/2023 |
0.2.0 | 3,906 | 7/17/2023 |
0.1.0 | 2,970 | 3/14/2023 |
0.1.0-beta | 945 | 2/8/2023 |