rajanadar / VaultSharp

A comprehensive cross-platform .NET Library for HashiCorp's Vault, a secret management tool
http://rajanadar.github.io/VaultSharp
Apache License 2.0
493 stars 134 forks source link
csharp dotnet dotnet-standard hashicorp-vault restclient secret

VaultSharp

The most comprehensive cross-platform .NET Library for HashiCorp's Vault - A Secret Management System.

VaultSharp NuGet: NuGet

VaultSharp Latest Documentation: Inline Below and also at: https://rajanadar.github.io/VaultSharp/

VaultSharp Questions/Clarifications: Ask on Stack Overflow with the tag vaultsharp

VaultSharp Gitter Lobby: Gitter Lobby

Report Issues/Feedback: Create a VaultSharp GitHub issue

Contributing Guidlines: VaultSharp Contribution Guidelines

NuGet
Join the chat at https://gitter.im/rajanadar-VaultSharp/Lobby License Build status

What is VaultSharp?

VaultSharp has been re-designed ground up, to give a structured user experience across the various auth methods, secrets engines & system apis. Also, the Intellisense on IVaultClient class should help. I have tried to add a lot of documentation.

Give me a quick snippet for use!

// Initialize one of the several auth methods.
IAuthMethodInfo authMethod = new TokenAuthMethodInfo("MY_VAULT_TOKEN");

// Initialize settings. You can also set proxies, custom delegates etc. here.
var vaultClientSettings = new VaultClientSettings("https://MY_VAULT_SERVER:8200", authMethod);

IVaultClient vaultClient = new VaultClient(vaultClientSettings);

// Use client to read a key-value secret.

// Very important to provide mountpath and secret name as two separate parameters. Don't provide a single combined string.
// Please use named parameters for 100% clarity of code. (the method also takes version and wrapTimeToLive as params)

Secret<SecretData> kv2Secret = await vaultClient.V1.Secrets.KeyValue.V2
                               .ReadSecretAsync(path: "secretPath", mountPoint: "mountPointIfNotDefault");

// Generate a dynamic Consul credential
Secret<ConsulCredentials> consulCreds = await vaultClient.V1.Secrets.Consul.GetCredentialsAsync(consulRole, consulMount);
string consulToken = consulCreds.Data.Token;

Gist of the features

VaultSharp - Supported .NET Platforms and Implementations

VaultSharp is built on .NET Standard 1.3 & .NET Standard 2.0 & .NET Standard 2.1 & .NET Frameworks 4.5, 4.6.x, 4.7.x, 4.8 & .NET 5, .NET 6, .NET 7, .NET 8. This makes it highly compatible and cross-platform.

The following implementations are supported due to that.

Source: https://github.com/dotnet/standard/blob/master/docs/versions.md

VaultSharp will follow the .NET EOL dates mentioned here:

VaultSharp and Consul Support

VaultSharp and Automatic Token Refresh

VaultSharp and VaultClient Dependency Injection Lifetime

VaultSharp and Automatic Built-in Client Side failover

VaultSharp and Immediate Login Failure Detection

IVaultClient vaultClient = new VaultClient(vaultClientSettings);
vaultClient.V1.Auth.PerformImmediateLogin();

Auth Methods

AliCloud Auth Method

// setup the AliCloud based auth to get the right token.

IAuthMethodInfo authMethod = new AliCloudAuthMethodInfo(roleName, base64EncodedIdentityRequestUrl, base64EncodedIdentityRequestHeaders);
var vaultClientSettings = new VaultClientSettings("https://MY_VAULT_SERVER:8200", authMethod);

IVaultClient vaultClient = new VaultClient(vaultClientSettings);

// any operations done using the vaultClient will use the
// vault token/policies mapped to the AliCloud jwt

App Role Auth Method

// setup the AppRole based auth to get the right token.

IAuthMethodInfo authMethod = new AppRoleAuthMethodInfo(roleId, secretId);
var vaultClientSettings = new VaultClientSettings("https://MY_VAULT_SERVER:8200", authMethod);

IVaultClient vaultClient = new VaultClient(vaultClientSettings);

// any operations done using the vaultClient will use the
// vault token/policies mapped to the app role and secret id.

AWS Auth Method

AWS Auth method has 2 flavors. An EC2 way and an IAM way. Here are examples for both.

AWS Auth Method - EC2
// setup the AWS-EC2 based auth to get the right token.

IAuthMethodInfo authMethod = new EC2AWSAuthMethodInfo(pkcs7, null, null, nonce, roleName);
var vaultClientSettings = new VaultClientSettings("https://MY_VAULT_SERVER:8200", authMethod);

IVaultClient vaultClient = new VaultClient(vaultClientSettings);

// any operations done using the vaultClient will use the
// vault token/policies mapped to the aws-ec2 role
// setup the AWS-EC2 based auth to get the right token.

IAuthMethodInfo authMethod = new EC2AWSAuthMethodInfo(null, identity, signature, nonce, roleName);
var vaultClientSettings = new VaultClientSettings("https://MY_VAULT_SERVER:8200", authMethod);

IVaultClient vaultClient = new VaultClient(vaultClientSettings);

// any operations done using the vaultClient will use the
// vault token/policies mapped to the aws-ec2 role
AWS Auth Method - IAM
// setup the AWS-IAM based auth to get the right token.

// Step 1: Pull the following NuGet Packages

// 1. AWSSDK.Core
// 2. AWSSDK.SecurityToken

// Step 2: Boiler-plate code to generate the Signed AWS STS Headers.

var amazonSecurityTokenServiceConfig = new AmazonSecurityTokenServiceConfig();

// If you are running VaultSharp on a real EC2 instance, use the following line of code.
// var awsCredentials = new InstanceProfileAWSCredentials();

// If you are running VaultSharp on a non-EC2 instance like local dev boxes or non-AWS environment, use the following line of code.

AWSCredentials awsCredentials = new StoredProfileAWSCredentials(); // picks up the credentials from your profile.
// AWSCredentials awsCredentials = new BasicAWSCredentials(accessKey: "YOUR_ACCESS_KEY", secretKey: "YOUR_SECRET_KEY"); // explicit credentials

var iamRequest = GetCallerIdentityRequestMarshaller.Instance.Marshall(new GetCallerIdentityRequest());

iamRequest.Endpoint = new Uri(amazonSecurityTokenServiceConfig.DetermineServiceURL());
iamRequest.ResourcePath = "/";

iamRequest.Headers.Add("User-Agent", "https://github.com/rajanadar/vaultsharp/0.11.1000");
iamRequest.Headers.Add("X-Amz-Security-Token", awsCredentials.GetCredentials().Token);
iamRequest.Headers.Add("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");

new AWS4Signer().Sign(iamRequest, amazonSecurityTokenServiceConfig, new RequestMetrics(), awsCredentials.GetCredentials().AccessKey, awsCredentials.GetCredentials().SecretKey);

// This is the point, when you have the final set of required Headers.
var iamSTSRequestHeaders = iamRequest.Headers;

// Step 3: Convert the headers into a base64 value needed by Vault.

var base64EncodedIamRequestHeaders = Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(iamSTSRequestHeaders)));

// Step 4: Setup the IAM AWS Auth Info.

IAuthMethodInfo authMethod = new IAMAWSAuthMethodInfo(nonce: nonce, roleName: roleName, requestHeaders: base64EncodedIamRequestHeaders);
var vaultClientSettings = new VaultClientSettings("https://MY_VAULT_SERVER:8200", authMethod);

IVaultClient vaultClient = new VaultClient(vaultClientSettings);

// any operations done using the vaultClient will use the
// vault token/policies mapped to the aws-iam role

Azure Auth Method

// setup the Azure based auth to get the right token.

IAuthMethodInfo authMethod = new AzureAuthMethodInfo(roleName, jwt);
var vaultClientSettings = new VaultClientSettings("https://MY_VAULT_SERVER:8200", authMethod);

IVaultClient vaultClient = new VaultClient(vaultClientSettings);

// any operations done using the vaultClient will use the
// vault token/policies mapped to the azure jwt

CloudFoundry Auth Method

// setup the CloudFoundry based auth to get the right token.

IAuthMethodInfo authMethod = new CloudFoundryAuthMethodInfo(roleName, instanceCertContent, instanceKeyContent);
var vaultClientSettings = new VaultClientSettings("https://MY_VAULT_SERVER:8200", authMethod);

IVaultClient vaultClient = new VaultClient(vaultClientSettings);

// any operations done using the vaultClient will use the
// vault token/policies mapped to the CloudFoundry jwt
CloudFoundry Signature Creation
var signing_time = CloudFoundrySignatureProvider.GetFormattedSigningTime(DateTime.UtcNow);
var signature = CloudFoundrySignatureProvider.GetSignature(signingTime, cfInstanceCertContent, roleName, cfInstanceKeyContent);

GitHub Auth Method

IAuthMethodInfo authMethod = new GitHubAuthMethodInfo(personalAccessToken);
var vaultClientSettings = new VaultClientSettings("https://MY_VAULT_SERVER:8200", authMethod);

IVaultClient vaultClient = new VaultClient(vaultClientSettings);

// any operations done using the vaultClient will use the
// vault token/policies mapped to the github token.

Google Cloud Auth Method

// setup the Google Cloud based auth to get the right token.

IAuthMethodInfo authMethod = new GoogleCloudAuthMethodInfo(roleName, jwt);
var vaultClientSettings = new VaultClientSettings("https://MY_VAULT_SERVER:8200", authMethod);

IVaultClient vaultClient = new VaultClient(vaultClientSettings);

// any operations done using the vaultClient will use the
// vault token/policies mapped to the Google Cloud jwt

JWT/OIDC Auth Method

// setup the JWT/OIDC based auth to get the right token.

IAuthMethodInfo authMethod = new JWTAuthMethodInfo(roleName, jwt);
var vaultClientSettings = new VaultClientSettings("https://MY_VAULT_SERVER:8200", authMethod);

IVaultClient vaultClient = new VaultClient(vaultClientSettings);

// any operations done using the vaultClient will use the
// vault token/policies mapped to the jwt

Kubernetes Auth Method

// setup the Kubernetes based auth to get the right token.

IAuthMethodInfo authMethod = new KubernetesAuthMethodInfo(roleName, jwt);
var vaultClientSettings = new VaultClientSettings("https://MY_VAULT_SERVER:8200", authMethod);

IVaultClient vaultClient = new VaultClient(vaultClientSettings);

// any operations done using the vaultClient will use the
// vault token/policies mapped to the Kubernetes jwt

LDAP Authentication Backend

LDAP Authentication Login Method
IAuthMethodInfo authMethod = new LDAPAuthMethodInfo(userName, password);
var vaultClientSettings = new VaultClientSettings("https://MY_VAULT_SERVER:8200", authMethod);

IVaultClient vaultClient = new VaultClient(vaultClientSettings);

// any operations done using the vaultClient will use the
// vault token/policies mapped to the LDAP username and password.
LDAP Auth Backend - Groups and User management
await _authenticatedVaultClient.V1.Auth.LDAP.WriteGroupAsync(groupName, policies);
await _authenticatedVaultClient.V1.Auth.LDAP.ReadGroupAsync(groupName);
await _authenticatedVaultClient.V1.Auth.LDAP.ReadAllGroupsAsync();
await _authenticatedVaultClient.V1.Auth.LDAP.DeleteGroupAsync(groupName);

await _authenticatedVaultClient.V1.Auth.LDAP.WriteUserAsync(username, policies, groups);
await _authenticatedVaultClient.V1.Auth.LDAP.ReadUserAsync(username);
await _authenticatedVaultClient.V1.Auth.LDAP.ReadAllUsersAsync();
await _authenticatedVaultClient.V1.Auth.LDAP.DeleteUserAsync(username);

Kerberos Authentication Backend

Requires https://github.com/wintoncode/vault-plugin-auth-kerberos .

IAuthMethodInfo authMethod = new KerberosAuthMethodInfo(); // uses network credential by default.
// IAuthMethodInfo authMethod = new KerberosAuthMethodInfo(credentials); // use your own ICredentials
var vaultClientSettings = new VaultClientSettings("https://MY_VAULT_SERVER:8200", authMethod);

IVaultClient vaultClient = new VaultClient(vaultClientSettings);

// any operations done using the vaultClient will use the 
// vault token/policies mapped to the current ActiveDirectory/Kerberos identity.

If you are dealing with a keytab file and krb5 config file and want to use VaultSharp, you can do that using the following two steps:

OCI Auth Method


var requestHeaders = new Dictionary<string, object>
{
     {"date", new List<string> { "Fri, 22 Aug 2019 21:02:19 GMT" } },
     {"(request-target)", new List<string> { "get /v1/auth/oci/login/devrole" } },
     {"host", new List<string> { "127.0.0.1" } },
     {"content-type", new List<string> { "application/json" } },
     {"authorization", new List<string> { 
          "Signature algorithm=\"rsa-sha256\",headers=\"date (request-target) host\",keyId=\"ocid1.tenancy.oc1..aaaaaaaaba3pv6wkcr4jqae5f15p2b2m2yt2j6rx32uzr4h25vqstifsfdsq/ocid1.user.oc1..aaaaaaaat5nvwcna5j6aqzjcaty5eqbb6qt2jvpkanghtgdaqedqw3rynjq/73:61:a2:21:67:e0:df:be:7e:4b:93:1e:15:98:a5:b7\",signature=\"GBas7grhyrhSKHP6AVIj/h5/Vp8bd/peM79H9Wv8kjoaCivujVXlpbKLjMPeDUhxkFIWtTtLBj3sUzaFj34XE6YZAHc9r2DmE4pMwOAy/kiITcZxa1oHPOeRheC0jP2dqbTll8fmTZVwKZOKHYPtrLJIJQHJjNvxFWeHQjMaR7M=\",version=\"1\""
        } }
};

IAuthMethodInfo authMethod = new OCIAuthMethodInfo(roleName, requestHeaders);
var vaultClientSettings = new VaultClientSettings("https://MY_VAULT_SERVER:8200", authMethod);

IVaultClient vaultClient = new VaultClient(vaultClientSettings);

// any operations done using the vaultClient will use the
// vault token/policies mapped to the OCI entity.

Okta Auth Method

IAuthMethodInfo authMethod = new OktaAuthMethodInfo(userName, password);
var vaultClientSettings = new VaultClientSettings("https://MY_VAULT_SERVER:8200", authMethod);

IVaultClient vaultClient = new VaultClient(vaultClientSettings);

// any operations done using the vaultClient will use the
// vault token/policies mapped to the Okta username and password.
Okta Verify

string nonce = "<nonce>";
var challengeResponse = await vaultClient.V1.Auth.Okta.VerifyPushChallengeAsync(nonce);
var answer = challengeResponse.Data.CorrectAnswer;

// verify this answer

RADIUS Auth Method

IAuthMethodInfo authMethod = new RADIUSAuthMethodInfo(userName, password);
var vaultClientSettings = new VaultClientSettings("https://MY_VAULT_SERVER:8200", authMethod);

IVaultClient vaultClient = new VaultClient(vaultClientSettings);

// any operations done using the vaultClient will use the
// vault token/policies mapped to the RADIUS username and password.

Certificate (TLS) Auth Method

// Please note that the certificate needs to be in pkcs12 format with a private key.
// Turn your cert + key into pkcs12 format with the following command:

// openssl pkcs12 -export -out Cert.p12 -in your-cert.pem -inkey your-key.pem

var certificate = new X509Certificate2(your-p12-bytes, your-pass);

IAuthMethodInfo authMethod = new CertAuthMethodInfo(certificate);

// Optionally, you can also provide a Certificate Role Name during Auth.
// IAuthMethodInfo authMethod = new CertAuthMethodInfo(certificate, certificateRoleName);

// And if you want to use the full chain of client-certificates, then use this overload
// X509Certificate2Collection x509Certificate2Collection = <load the full chain of certs>;
// IAuthMethodInfo authMethod = new CertAuthMethodInfo(x509Certificate2Collection);

var vaultClientSettings = new VaultClientSettings("https://MY_VAULT_SERVER:8200", authMethod);

IVaultClient vaultClient = new VaultClient(vaultClientSettings);

// any operations done using the vaultClient will use the
// vault token/policies mapped to the client certificate.

Token Auth Method

Token Auth Login Method
IAuthMethodInfo authMethod = new TokenAuthMethodInfo(vaultToken);
var vaultClientSettings = new VaultClientSettings("https://MY_VAULT_SERVER:8200", authMethod);

IVaultClient vaultClient = new VaultClient(vaultClientSettings);

// any operations done using the vaultClient will use the
// vault token/policies mapped to the vault token.
Token Creation
CreateTokenRequest request = new CreateTokenRequest();

// CreateTokenRequest has options to create orphaned tokens, role based tokens etc. with attached policies.
Secret<object> tokenData = await _authenticatedVaultClient.V1.Auth.Token.CreateTokenAsync(request);
Token Lookup (any Token)
string token = "token-for-which-you-need-info";

Secret<ClientTokenInfo> tokenData = await _authenticatedVaultClient.V1.Auth.Token.LookupAsync(token);
Token Lookup (Calling Token)
Secret<CallingTokenInfo> tokenData = await _authenticatedVaultClient.V1.Auth.Token.LookupSelfAsync();

Username and Password Auth Method

IAuthMethodInfo authMethod = new UserPassAuthMethodInfo(username, password);
var vaultClientSettings = new VaultClientSettings("https://MY_VAULT_SERVER:8200", authMethod);

IVaultClient vaultClient = new VaultClient(vaultClientSettings);

// any operations done using the vaultClient will use the
// vault token/policies mapped to the username/password.

Custom Auth Method - Bring your own Vault Token

// Func<Task<CustomAuthMethodInfo>> getCustomAuthMethodInfoAsync = a custom async method to return the vault token.
IAuthMethodInfo authMethod = new CustomAuthMethodInfo("vault-server-auth-method", getCustomAuthMethodInfoAsync);
var vaultClientSettings = new VaultClientSettings("https://MY_VAULT_SERVER:8200", authMethod);

IVaultClient vaultClient = new VaultClient(vaultClientSettings);

// Once VaultSharp evaluates the delegate, VaultSharp can now provide you with the associated lease info for the Token as well.
// authMethod.ReturnedLoginAuthInfo has all the info including the token and renewal info.

App Id Auth Method (DEPRECATED)

MFA (LEGACY/UNSUPPORTED)

Force re-fetch of Vault Login

// when it is time to re-fetch the login token, just set this flag.
vaultClient.V1.Auth.ResetVaultToken();

Secrets Engines

All of the below examples assume that you have a vault client instance ready. e.g.

// Initialize one of the several auth methods.
IAuthMethodInfo authMethod = new TokenAuthMethodInfo("MY_VAULT_TOKEN");

// Initialize settings. You can also set proxies, custom delegates etc. here.
var vaultClientSettings = new VaultClientSettings("https://MY_VAULT_SERVER:8200", authMethod);

IVaultClient vaultClient = new VaultClient(vaultClientSettings);

Active Directory Secrets Engine

Retrieving Passwords (offering credentials)
Secret<ActiveDirectoryCredentials> adCreds = await vaultClient.V1.Secrets.ActiveDirectory.GetCredentialsAsync(role);
string currentPassword = adCreds.Data.CurrentPassword;

AliCloud Secrets Engine

Generate RAM Credentials

string accessKey = aliCloudCreds.Data.AccessKey; string secretKey = aliCloudCreds.Data.SecretKey; string securityToken = aliCloudCreds.Data.SecurityToken; string expiration = aliCloudCreds.Data.Expiration;


#### AWS Secrets Engine

##### Configure Root IAM Credential

- This endpoint configures the root IAM credentials to communicate with AWS.

```cs
var configureRootIAMCredentialsModel = new ConfigureRootIAMCredentialsModel
{
   AccessKey = "<>",
   SecretKey = "<>",
   Region = "<>"
};

await vaultClient.V1.Secrets.AWS.ConfigureRootIAMCredentialsAsync(configureRootIAMCredentialsModel);
Read Root IAM Credential

Secret<RootIAMCredentialsConfigModel> config = await vaultClient.V1.Secrets.AWS.GetRootIAMCredentialsConfigAsync();
Rotate Root IAM Credential

Secret<RotateRootIAMCredentialsResponseModel> response = await vaultClient.V1.Secrets.AWS.RotateRootIAMCredentialsAsync();

string newAccessKey = response.Data.NewAccessKey;
Configure Lease
var leaseConfigModel = new AWSLeaseConfigModel
{
   Lease = "36h",
   MaximumLease = "72h"
};

await vaultClient.V1.Secrets.AWS.ConfigureLeaseAsync(leaseConfigModel);
Read Lease

Secret<AWSLeaseConfigModel> lease = await vaultClient.V1.Secrets.AWS.GetLeaseConfigAsync();
Write Role
var role = new CreateAWSRoleModel
{
   CredentialType = AWSCredentialsType.federation_token,
   PolicyDocument = "{\"Version\": \"...\"}"
};

await vaultClient.V1.Secrets.AWS.WriteRoleAsync("my-role-name", role);
Read Role
Secret<AWSRoleModel> role = await vaultClient.V1.Secrets.AWS.ReadRoleAsync(roleName);
List<AWSCredentialsType> credTypes = role.Data.CredentialTypes;
Read All Roles
Secret<ListInfo> roles = await vaultClient.V1.Secrets.AWS.ReadAllRolesAsync();
List<string> names = roles.Data;
Generate IAM Credentials
Secret<AWSCredentials> awsCreds = await vaultClient.V1.Secrets.AWS.GetCredentialsAsync(role);

string accessKey = awsCreds.Data.AccessKey;
string secretKey = awsCreds.Data.SecretKey;
string securityToken = awsCreds.Data.SecurityToken;
Generate IAM Credentials with STS
Secret<AWSCredentials> awsCreds = await vaultClient.V1.Secrets.AWS.GenerateSTSCredentialsAsync(role, ttl);

string accessKey = awsCreds.Data.AccessKey;
string secretKey = awsCreds.Data.SecretKey;
string securityToken = awsCreds.Data.SecurityToken;

Azure Secrets Engine

Generate dynamic Azure credentials
Secret<AzureCredentials> azureCredentials = await vaultClient.V1.Secrets.Azure.GetCredentialsAsync(roleName);
string clientId = azureCredentials.Data.ClientId;
string clientSecret = azureCredentials.Data.ClientSecret;

Consul Secrets Engine

// Generate a dynamic Consul credential
Secret<ConsulCredentials> consulCreds = await vaultClient.V1.Secrets.Consul.GetCredentialsAsync(consulRole);
string consulToken = consulCredentials.Data.Token;

Cubbyhole Secrets Engine

Read Secret
Secret<Dictionary<string, object>> secret = await vaultClient.V1.Secrets.Cubbyhole.ReadSecretAsync(secretPath);
Dictionary<string, object> secretValues = secret.Data;
List Secrets
Secret<ListInfo> secret = await vaultClient.V1.Secrets.Cubbyhole.ReadSecretPathsAsync(folderPath);
ListInfo paths = secret.Data;
Create/Update Secret
var value = new Dictionary<string, object> { { "key1", "val1" }, { "key2", 2 } };
await vaultClient.V1.Secrets.Cubbyhole.WriteSecretAsync(secretPath, value);
Delete Secret
await vaultClient.V1.Secrets.Cubbyhole.DeleteSecretAsync(secretPath);

Databases Secrets Engine

Generate dynamic DB credentials
Secret<UsernamePasswordCredentials> dbCreds = await vaultClient.V1.Secrets.Database.GetCredentialsAsync(role);
string username = dbCreds.Data.Username;
string password = dbCreds.Data.Password;
Create, Read and Delete Database Roles (please see next section for static db roles)
await vaultClient.V1.Secrets.Database.CreateRoleAsync(roleName, roleRequest);

await vaultClient.V1.Secrets.Database.ReadRoleAsync(roleName);

await vaultClient.V1.Secrets.Database.ReadAllRolesAsync();

await vaultClient.V1.Secrets.Database.DeleteRoleAsync(roleName);
Create, Read and Delete Static Database Roles
await vaultClient.V1.Secrets.Database.CreateStaticRoleAsync(roleName, roleRequest);

await vaultClient.V1.Secrets.Database.ReadStaticRoleAsync(roleName);

await vaultClient.V1.Secrets.Database.ReadAllStaticRolesAsync();

await vaultClient.V1.Secrets.Database.DeleteStaticRoleAsync(roleName);
Generate Static DB credentials
Secret<StaticCredentials> dbCreds = await vaultClient.V1.Secrets.Database.GetStaticCredentialsAsync(role);
Rotate static DB credentials
await vaultClient.V1.Secrets.Database.RotateStaticCredentialsAsync(role);

Google Cloud Secrets Engine

Generate Secret (IAM Service Account Creds): OAuth2 Access Token
Secret<GoogleCloudOAuth2Token> oauthSecret = await vaultClient.V1.Secrets.GoogleCloud.GetOAuth2TokenAsync(roleset);
string token = oauthSecret.Data.Token;
Generate Secret (IAM Service Account Creds): Service Account Key
Secret<GoogleCloudServiceAccountKey> privateKeySecret = await vaultClient.V1.Secrets.GoogleCloud.GenerateServiceAccountKeyAsync(roleset, keyAlgorithm, privateKeyType);
string privateKeyData = privateKeySecret.Data.Base64EncodedPrivateKeyData;

Google Cloud KMS Secrets Engine

Encrypt, Decrypt, ReEncrypt, Sign & Verify
await vaultClient.V1.Secrets.GoogleCloudKMS.EncryptAsync(keyName, requestOptions);
await vaultClient.V1.Secrets.GoogleCloudKMS.DecryptAsync(keyName, requestOptions);
await vaultClient.V1.Secrets.GoogleCloudKMS.ReEncryptAsync(keyName, requestOptions);
await vaultClient.V1.Secrets.GoogleCloudKMS.SignAsync(keyName, requestOptions);
await vaultClient.V1.Secrets.GoogleCloudKMS.VerifyAsync(keyName, requestOptions);

Key Value Secrets Engine

Key Value Secrets Engine - V1
Create/Update Secret
var value = new Dictionary<string, object> { { "key1", "val1" }, { "key2", 2 } };
var writtenValue = await vaultClient.V1.Secrets.KeyValue.V1.WriteSecretAsync(secretPath, value);
Read Secret
// Use client to read a v1 key-value secret.
Secret<Dictionary<string, object>> kv1Secret = await vaultClient.V1.Secrets.KeyValue.V1.ReadSecretAsync("v1-secret-name");
Dictionary<string, object> dataDictionary = kv1Secret.Data;
List Secrets
Secret<ListInfo> secret = await vaultClient.V1.Secrets.KeyValue.V1.ReadSecretPathsAsync(path);
ListInfo paths = secret.Data;
Delete Secret
await vaultClient.V1.Secrets.KeyValue.V1.DeleteSecretAsync(secretPath);
Key Value Secrets Engine - V2
Create/Update Secret
var value = new Dictionary<string, object> { { "key1", "val1" }, { "key2", 2 } };
var writtenValue = await vaultClient.V1.Secrets.KeyValue.V2.WriteSecretAsync(secretPath, value, checkAndSet);
Patch Secret

var valueToBeCombined = new Dictionary<string, object> { { "key2", "new-val2" }, { "key3", "val3" } };

var patchSecretDataRequest = new PatchSecretDataRequest() { Data = valueToBeCombined };

var metadata = await vaultClient.V1.Secrets.KeyValue.V2.PatchSecretAsync(secretPath, valueToBeCombined);
Read Secret
// Use client to read a v2 key-value secret.

// Very important to provide mountpath and secret name as two separate parameters. Don't provide a single combined string.
// Please use named parameters for 100% clarity of code. (the method also takes version and wrapTimeToLive as params)

Secret<Dictionary<string, object>> kv2Secret = await vaultClient.V1.Secrets.KeyValue.V2
                               .ReadSecretAsync(path: "v2-secret-name", mountPoint: "mountPointIfNotDefault");

Dictionary<string, object> dataDictionary = kv2Secret.Data;
Write Metadata
var writeCustomMetadataRequest = new CustomMetadataRequest
            {
                CustomMetadata = new Dictionary<string, string>
                {
                    { "owner", "system"},
                    { "expired_in", "20331010"}
                }
            };

 await _authenticatedVaultClient.V1.Secrets.KeyValue.V2.WriteSecretMetadataAsync(path, writeCustomMetadataRequest, mountPoint: kv2SecretsEngine.Path);
Patch Metadata
 var patchCustomMetadataRequest = new CustomMetadataRequest
            {
                CustomMetadata = new Dictionary<string, string>
                {
                    { "locale", "EN"},
                    { "expired_in", "20341010"}
                }
            };

 await _authenticatedVaultClient.V1.Secrets.KeyValue.V2.PatchSecretMetadataAsync(path, patchCustomMetadataRequest, mountPoint: kv2SecretsEngine.Path)
Read Metadata
Secret<FullSecretMetadata> kv2SecretMetadata = await vaultClient.V1.Secrets.KeyValue.V2.ReadSecretMetadataAsync("v1-secret-name");
List Secrets
Secret<ListInfo> secret = await vaultClient.V1.Secrets.KeyValue.V2.ReadSecretPathsAsync(path);
ListInfo paths = secret.Data;
Read Secret Subkeys
Delete Secret
await vaultClient.V1.Secrets.KeyValue.V2.DeleteSecretAsync(secretPath);
Delete Secret Versions
await vaultClient.V1.Secrets.KeyValue.V2.DeleteSecretVersionsAsync(secretPath, versions);
Undelete Secret Versions
await vaultClient.V1.Secrets.KeyValue.V2.UndeleteSecretVersionsAsync(secretPath, versions);
Destroy Secret
await vaultClient.V1.Secrets.KeyValue.V2.DestroySecretAsync(secretPath, new List<int> { 1, 2 });
Delete Secret Metadata and all versions

Identity Secrets Engine

Generate a Signed ID Token
Secret<IdentityToken> token = await vaultClient.V1.Secrets.Identity.GetTokenAsync(roleName);
string clientId = token.Data.ClientId;
string token = token.Data.Token;
Introspect a signed ID Token
Secret<bool> activeResponse = await vaultClient.V1.Secrets.Identity.IntrospectTokenAsync(token, clientId);
bool active = activeResponse.Data;

KeyManagement Secrets Engine (Enterprise)

Read Key
Secret<KeyManagementKey> keyManagementKey = await vaultClient.V1.Secrets.Enterprise.KeyManagement.ReadKeyAsync(keyName);
var keys = keyManagementKey.Data.Keys;
Read Key in KMS
Secret<KeyManagementKMSKey> keyManagementKMSKey = await vaultClient.V1.Secrets.Enterprise.KeyManagement.ReadKeyInKMSAsync(kmsName, keyName);
var name = keyManagementKMSKey.Data.Name;
var purpose = keyManagementKMSKey.Data.Purpose;
var protection = keyManagementKMSKey.Data.Protection;

KMIP Secrets Engine (Enterprise)

Generate dynamic credentials
Secret<KMIPCredentials> kmipCredentials = await vaultClient.V1.Secrets.Enterprise.KMIP.GetCredentialsAsync(scopeName, roleName);
string certificateContent = kmipCredentials.Data.CertificateContent;
string privateKeyContent = kmipCredentials.Data.PrivateKeyContent;

Kubernetes Secrets Engine

Generate dynamic credentials
Secret<KubernetesCredentials> kubernetesCredentials = await vaultClient.V1.Secrets.Kubernetes.GetCredentialsAsync(ksRoleName, ksNamespace);
string serviceAccountToken = kubernetesCredentials.Data.ServiceAccountToken;

MongoDBAtlas Secrets Engine

Generate dynamic credentials
Secret<MongoDBAtlasCredentials> creds = await vaultClient.V1.Secrets.MongoDBAtlas.GetCredentialsAsync(name);
string privateKey = creds.Data.PrivateKey;
string publicKey = creds.Data.PublicKey;

Nomad Secrets Engine

Generate dynamic credentials
Secret<NomadCredentials> nomadCredentials = await vaultClient.V1.Secrets.Nomad.GetCredentialsAsync(roleName);
string accessorId = nomadCredentials.Data.AccessorId;
string secretId = nomadCredentials.Data.SecretId;

OpenLDAP Secrets Engine

Generate dynamic role credentials
Secret<LDAPCredentials> credentials = await vaultClient.V1.Secrets.OpenLDAP.GetDynamicCredentialsAsync(roleName);
string username = credentials.Data.Username;
string password = credentials.Data.Password;
Generate static role credentials
Secret<StaticCredentials> credentials = await vaultClient.V1.Secrets.OpenLDAP.GetStaticCredentialsAsync(roleName);
string username = credentials.Data.Username;
string password = credentials.Data.Password;

PKI (Certificates) Secrets Engine

Generate credentials
var certificateCredentialsRequestOptions = new CertificateCredentialsRequestOptions { // initialize };
Secret<CertificateCredentials> certSecret = await vaultClient.V1.Secrets.PKI.GetCredentialsAsync(pkiRoleName, certificateCredentialsRequestOptions);

string privateKeyContent = certSecret.Data.PrivateKeyContent;
Sign Certificate
var signCertificateRequestOptions = new SignCertificateRequestOptions { // initialize };
Secret<SignedCertificateData> certSecret = await vaultClient.V1.Secrets.PKI.SignCertificateAsync(pkiRoleName, signCertificateRequestOptions);

string certificateContent = certSecret.Data.CertificateContent;
Revoke Certificate
Secret<RevokeCertificateResponse> revoke = await vaultClient.V1.Secrets.PKI.RevokeCertificateAsync(serialNumber);
long revocationTime = revoke.Data.RevocationTime;
Tidy up Certificate Storage
var request = new CertificateTidyRequest { TidyCertStore = false, TidyRevokedCerts = true };
await vaultClient.V1.Secrets.PKI.TidyAsync(request);
Configure Automatic Tidying up of Certificate Storage
var request = new CertificateAutoTidyRequest { TidyCertStore = false, TidyRevokedCerts = true };
await vaultClient.V1.Secrets.PKI.AutoTidyAsync(request);
Get Status of Certificate Tidying Process
var tidyStatus = await vaultClient.V1.Secrets.PKI.GetTidyStatusAsync();
CertificateTidyState state = tidyStatus.Data.TidyState;
Cancel Certificate Tidying Process
var tidyStatus = await vaultClient.V1.Secrets.PKI.CancelTidyAsync();
CertificateTidyState state = tidyStatus.Data.TidyState;
List certificates
var keys = await vaultClient.V1.Secrets.PKI.ListCertificatesAsync(mountpoint);
Assert.IsTrue(keys.Any(k => k == "17:67:16:b0:b9:45:58:c0:3a:29:e3:cb:d6:98:33:7a:a6:3b:66:c1"));
List revoked certificates
var keys = await vaultClient.V1.Secrets.PKI.ListRevokedCertificatesAsync(mountpoint);
Assert.IsTrue(keys.Any(k => k == "17:67:16:b0:b9:45:58:c0:3a:29:e3:cb:d6:98:33:7a:a6:3b:66:c1"));
Read certificate
var cert = await vaultClient.V1.Secrets.PKI.ReadCertificateAsync("17:67:16:b0:b9:45:58:c0:3a:29:e3:cb:d6:98:33:7a:a6:3b:66:c1", mountpoint);
Assert.NotNull(cert.CertificateContent);
Read CA Certificate
var caCert = await vaultClient.V1.Secrets.PKI.ReadCACertificateAsync(CertificateFormat.pem, mountpoint);
Assert.NotNull(caCert.CertificateContent);

RabbitMQ Secrets Engine

Generate dynamic DB credentials
Secret<UsernamePasswordCredentials> secret = await vaultClient.V1.Secrets.RabbitMQ.GetCredentialsAsync(roleName);
string username = secret.Data.Username;
string password = secret.Data.Password;
Create, Read and Delete RabbitMQ Roles
var virtualHostName = "/";
var virtualHostPermission = new { write = ".*", read = ".*" };
var virtualHosts = new Dictionary<string, object>() { { virtualHostName, virtualHostPermission } };
var virtualHostsJson = JsonSerializer.Serialize(virtualHosts);
var role = new RabbitMQRole() { VHosts = virtualHostsJson }        
await vaultClient.V1.Secrets.RabbitMQ.CreateRoleAsync(roleName, role, mountPoint);

await vaultClient.V1.Secrets.RabbitMQ.ReadRoleAsync(roleName, mountPoint);

await vaultClient.V1.Secrets.RabbitMQ.DeleteRoleAsync(roleName, mountPoint);

SSH Secrets Engine

Generate SSH credentials
Secret<SSHCredentials> sshCreds = await vaultClient.V1.Secrets.SSH.GetCredentialsAsync(role, ipAddress, username);
string sshKey = sshCreds.Data.Key;
SSH key signing

Terraform Cloud Secrets Engine

Generate credentials
Secret<TerraformCredentials> secret = await vaultClient.V1.Secrets.Terraform.GetCredentialsAsync(role);
string token = secret.Data.Token;
string tokenId = secret.Data.TokenId;

TOTP Secrets Engine

Generate Code

This endpoint generates a new time-based one-time use password based on the named key.

Secret<TOTPCode> totpSecret = await vaultClient.V1.Secrets.TOTP.GetCodeAsync(keyName);
string code = totpSecret.Data.Code;
Validate Code

This endpoint validates a time-based one-time use password generated from the named key.

Secret<TOTPCodeValidity> totpValidity = await vaultClient.V1.Secrets.TOTP.ValidateCodeAsync(keyName, code);
bool valid = totpValidity.Data.Valid;
Create TOTP Key

This endpoint creates or updates a key definition. You can create both Vault based or non-vault based keys.


TOTPCreateKeyRequest request = new TOTPCreateKeyRequest
{
 Issuer = "Google",
 AccountName = "scooby@gmail.com",
 KeyGenerationOption = new TOTPVaultBasedKeyGeneration { // specific stuff }
 // for non-vault based, use new TOTPNonVaultBasedKeyGeneration { // specific stuff }
};

Secret<TOTPCreateKeyResponse> response = await vaultClient.V1.Secrets.TOTP.CreateKeyAsync(keyName, request);
var barcode = response.Data.Barcode;
Read Key

This endpoint queries the key definition.

Secret<TOTPKey> key = await vaultClient.V1.Secrets.TOTP.ReadKeyAsync(keyName);
Read all Keys

This endpoint returns a list of available keys. Only the key names are returned, not any values.

Secret<ListInfo> keys = await vaultClient.V1.Secrets.TOTP.ReadAllKeysAsync();
Delete Key

This endpoint deletes the key definition.

await vaultClient.V1.Secrets.TOTP.DeleteKeyAsync(keyName);

Transform Secrets Engine (Enterprise)

Encode Method
Encode Single Item

var encodeOptions = new EncodeRequestOptions { Value = "ipsem" };
Secret<EncodedResponse> response = await _authenticatedVaultClient.V1.Secrets.Enterprise.Transform.EncodeAsync(roleName, encodeOptions);
response.Data.EncodedValue;
Encode Batched Items
var encodeOptions = new EncodeRequestOptions 
{ 
  BatchItems = new List<EncodingItem> { new EncodingItem { Value = "ipsem1" }, new EncodingItem { Value = "ipsem2" } }
};

Secret<EncodedResponse> response = await _authenticatedVaultClient.V1.Secrets.Enterprise.Transform.EncodeAsync(roleName, encodeOptions);
response.Data.EncodedItems;
Decode Method
Decode Single Item
var decodeOptions = new DecodeRequestOptions { Value = "ipsem" };
Secret<DecodedResponse> response = await _authenticatedVaultClient.V1.Secrets.Enterprise.Transform.DecodeAsync(roleName, decodeOptions);
response.Data.DecodedValue;
Decode Batched Item
var decodeOptions = new DecodeRequestOptions 
{ 
  BatchItems = new List<DecodingItem> { new DecodingItem { Value = "ipsem1" }, new DecodingItem { Value = "ipsem2" } }
};

Secret<DecodedResponse> response = await _authenticatedVaultClient.V1.Secrets.Enterprise.Transform.DecodeAsync(roleName, decodeOptions);
response.Data.DecodedItems;

Transit Secrets Engine

Encrypt Method
Encrypt Single Item
var keyName = "test_key";

var context = "context1";
var plainText = "raja";
var encodedPlainText = Convert.ToBase64String(Encoding.UTF8.GetBytes(plainText));
var encodedContext = Convert.ToBase64String(Encoding.UTF8.GetBytes(context));

var encryptOptions = new EncryptRequestOptions
{
    Base64EncodedPlainText = encodedPlainText,
    Base64EncodedContext = encodedContext,
};

Secret<EncryptionResponse> encryptionResponse = await _authenticatedVaultClient.V1.Secrets.Transit.EncryptAsync(keyName, encryptOptions);
string cipherText = encryptionResponse.Data.CipherText;
Encrypt Batched Items
var encryptOptions = new EncryptRequestOptions
{
    BatchedEncryptionItems = new List<EncryptionItem>
    {
        new EncryptionItem { Base64EncodedContext = encodedContext1, Base64EncodedPlainText = encodedPlainText1 },
        new EncryptionItem { Base64EncodedContext = encodedContext2, Base64EncodedPlainText = encodedPlainText2 },
        new EncryptionItem { Base64EncodedContext = encodedContext3, Base64EncodedPlainText = encodedPlainText3 },
    }
};

Secret<EncryptionResponse> encryptionResponse = await _authenticatedVaultClient.V1.Secrets.Transit.EncryptAsync(keyName, encryptOptions);
string firstCipherText = encryptionResponse.Data.BatchedResults.First().CipherText;
Decrypt Method
Decrypt Single Item
var decryptOptions = new DecryptRequestOptions
{
    CipherText = cipherText,
    Base64EncodedContext = encodedContext,
};

Secret<DecryptionResponse> decryptionResponse = await _authenticatedVaultClient.V1.Secrets.Transit.DecryptAsync(keyName, decryptOptions);
string encodedPlainText = decryptionResponse.Data.Base64EncodedPlainText;
Decrypt Batched Item
var decryptOptions = new DecryptRequestOptions
{
    BatchedDecryptionItems = new List<DecryptionItem>
    {
        new DecryptionItem { Base64EncodedContext = encodedContext1, CipherText = cipherText1 },
        new DecryptionItem { Base64EncodedContext = encodedContext2, CipherText = cipherText2 },
        new DecryptionItem { Base64EncodedContext = encodedContext3, CipherText = cipherText3 },
    }
};

Secret<DecryptionResponse> decryptionResponse = await _authenticatedVaultClient.V1.Secrets.Transit.DecryptAsync(keyName, decryptOptions);
string firstEncodedPlainText = decryptionResponse.Data.BatchedResults.First().Base64EncodedPlainText;
Generate Data Key
// Generate Data Key
var dataKeyOptions = new DataKeyRequestOptions
{
    Base64EncodedContext = encodedContext,
    Nonce = nonce
};

Secret<DataKeyResponse> dataKeyResponse = await _authenticatedVaultClient.V1.Secrets.Transit.GenerateDataKeyAsync(keyType, keyName, dataKeyOptions);

var encodedDataKeyPlainText = dataKeyResponse.Data.Base64EncodedPlainText;
var dataKeyCipherText = dataKeyResponse.Data.Base64EncodedCipherText;
Read all Encryption Keys
var allKeys = await _authenticatedVaultClient.V1.Secrets.Transit.ReadAllEncryptionKeysAsync();
Trim Key

var trimOptions = new TrimKeyRequestOptions { MinimumAvailableVersion = 2 };

await _authenticatedVaultClient.V1.Secrets.Transit.TrimKeyAsync(keyName, trimOptions);
Export Key

string version = "latest";

Secret<ExportedKeyInfo> exportedKeyInfo = await _authenticatedVaultClient.V1.Secrets.Transit.ExportKeyAsync(TransitKeyCategory.encryption_key, keyName, version);
Backup Key

var backup = await _authenticatedVaultClient.V1.Secrets.Transit.BackupKeyAsync(keyName);
string backupData = backup.Data.BackupData;
Restore Key

var restoreData = new RestoreKeyRequestOptions 
{
    BackupData = previouslyBackedUpData, 
    Force = true 
};
await _authenticatedVaultClient.V1.Secrets.Transit.RestoreKeyAsync(keyName, restoreData);
Generate Random Bytes
var byteCountRequested = 64;
var randomOpts = new RandomBytesRequestOptions 
{
    Format = OutputEncodingFormat.base64
};
var base64Response = await _authenticatedVaultClient.V1.Secrets.Transit.GenerateRandomBytesAsync(byteCountRequested, randomOpts);
var base64EncodedRandomData = base64Response.Data.EncodedRandomBytes;
Hash Data String
var hashOpts = new HashRequestOptions
{
    Format = OutputEncodingFormat.base64, 
    Base64EncodedInput = encodedStringToHash
};
var hashResponse = await _authenticatedVaultClient.V1.Secrets.Transit.HashDataAsync(HashAlgorithm.sha2_256, hashOpts);
var hashString = hashResponse.Data.HashSum;
Generate HMAC Single Item
var hmacOptions = new HmacRequestOptions 
{
    Base64EncodedInput = encodedPlainText
};
var hmacResponse = await _authenticatedVaultClient.V1.Secrets.Transit.GenerateHmacAsync(HashAlgorithm.sha2_256, keyName, hmacOptions);
Generate HMAC Batch Item
var hmacList = new HmacRequestOptions
{
    BatchInput = new List<HmacSingleInput>
    {
        new HmacSingleInput {Base64EncodedInput = encodedText},
        new HmacSingleInput {Base64EncodedInput = encodedText2},
        new HmacSingleInput {Base64EncodedInput = encodedText3}
    }
};
var hmacResponse = await _authenticatedVaultClient.V1.Secrets.Transit.GenerateHmacAsync(HashAlgorithm.sha2_256, keyName, hmacList);
Sign Single Item
var signOptions = new SignRequestOptions
{
    Base64EncodedInput = encodedText,
    SignatureAlgorithm = SignatureAlgorithm.Pkcs1v15,
    MarshalingAlgorithm = MarshalingAlgorithm.Asn1
};
var signResponse = await _authenticatedVaultClient.V1.Secrets.Transit.SignDataAsync(HashAlgorithm.sha2_256, keyName, signOptions);
Sign Batched Item
 var signList = new SignRequestOptions
{
    BatchInput = new List<SignSingleInput>
    {
        new SignSingleInput {Base64EncodedInput = encodedText},
        new SignSingleInput {Base64EncodedInput = encodedText2},
        new SignSingleInput {Base64EncodedInput = encodedText3}
    },
    SignatureAlgorithm = SignatureAlgorithm.Pkcs1v15,
    MarshalingAlgorithm = MarshalingAlgorithm.Asn1
};
var signResponse = await _authenticatedVaultClient.V1.Secrets.Transit.SignDataAsync(HashAlgorithm.sha2_256, keyName, signList);
Verify HMAC Single Item
var verifyOptions = new VerifyRequestOptions
{
    Base64EncodedInput = base64Input,
    Hmac = hmacToVerify,
    MarshalingAlgorithm = MarshalingAlgorithm.Asn1
};
var verifyResponse = await _authenticatedVaultClient.V1.Secrets.Transit.VerifySignedDataAsync(HashAlgorithm.sha2_256, keyName, verifyOptions);
var isValid = verifyResponse.Data.Valid;
Verify Signature Single Item
var verifyOptions = new VerifyRequestOptions
{
    Base64EncodedInput = base64Input,
    Signature = signResponse.Data.Signature,
    SignatureAlgorithm = SignatureAlgorithm.Pkcs1v15,
    MarshalingAlgorithm = MarshalingAlgorithm.Asn1
};
var verifyResponse = await _authenticatedVaultClient.V1.Secrets.Transit.VerifySignedDataAsync(HashAlgorithm.sha2_256, keyname, verifyOptions);
var isValid = verifyResponse.Data.Valid;
Read Transit Cache Configuration
var cacheResult = await _authenticatedVaultClient.V1.Secrets.Transit.ReadCacheConfigAsync();
var cacheSize = cacheResult.Data.Size;
Configure Cache
var cacheOptions = new CacheConfigRequestOptions 
{
    Size = cacheResult.Data.Size + 1 
};
await transit.SetCacheConfigAsync(cacheOptions);

System Backend

VaultSharp already supports several of the System backend features.

vaultClient.V1.System.<method> // The method you are looking for.

Can I inject my own HttpClient into VaultSharp?

What is the deal with the Versioning of VaultSharp?

Can I use it in my PowerShell Automation?

All the methods are async. How do I use them synchronously?

In Conclusion

Happy Coding folks!