New Vault OSS Now Includes Multi-factor Authentication! Learn more
  • Overview
    • Automated PKI Infrastructure
    • Data Encryption & Tokenization
    • Database Credential Rotation
    • Dynamic Secrets
    • Identity-based Access
    • Key Management
    • Kubernetes Secrets
    • Secrets Management
  • Enterprise
  • Tutorials
  • Docs
  • API
  • Community
GitHubTry Cloud
Download
    • v1.10.x (latest)
    • v1.9.x
    • v1.8.x
    • v1.7.x
    • v1.6.x
    • v1.5.x
    • v1.4.x
  • What is Vault?
  • Use Cases
    • CLI Quick Start
    • HCP Quick Start
    • Developer Quick Start

  • Browser Support
  • Installing Vault
    • Overview
    • Architecture
    • High Availability
    • Integrated Storage
    • Security Model
    • Telemetry
    • Token Authentication
    • Key Rotation
    • Replication
    • Limits and Maximums
    • Overview
    • 'Dev' Server
    • Seal/Unseal
    • Namespace API Lock
    • Lease, Renew, and Revoke
    • Authentication
    • Tokens
    • Identity
    • OIDC Provider
    • Response Wrapping
    • Policies
    • Password Policies
    • Username Templating
    • High Availability
    • Storage
      • Overview
      • Autopilot
    • PGP, GnuPG, and Keybase
    • Recovery Mode
    • Resource Quotas
      • Overview
      • FAQ
    • Transform
    • Mount Migration
    • Overview
      • Overview
      • TCP
    • replication
      • Overview
      • AliCloud KMS
      • AWS KMS
      • Azure Key Vault
      • GCP Cloud KMS
      • OCI KMS
      • HSM PKCS11 ENT
      • Vault Transit
    • sentinel
      • Overview
      • Consul
      • Kubernetes
      • Overview
      • Aerospike
      • Alicloud OSS
      • Azure
      • Cassandra
      • CockroachDB
      • Consul
      • CouchDB
      • DynamoDB
      • Etcd
      • Filesystem
      • FoundationDB
      • Google Cloud Spanner
      • Google Cloud Storage
      • In-Memory
      • Manta
      • MSSQL
      • MySQL
      • OCI Object Storage
      • PostgreSQL
      • Integrated Storage (Raft)
      • S3
      • Swift
      • Zookeeper
    • telemetry
    • ui
    • Log Completed Requests
    • Entropy Augmentation ENT
    • kms_library ENT
    • Overview
    • agent
      • Overview
      • disable
      • enable
      • list
      • Overview
      • disable
      • enable
      • help
      • list
      • move
      • tune
    • debug
    • delete
      • Overview
      • delete
      • destroy
      • enable-versioning
      • get
      • list
      • metadata
      • patch
      • put
      • rollback
      • undelete
      • Overview
      • lookup
      • renew
      • revoke
      • Overview
      • get
      • inspect
    • list
    • login
    • monitor
    • namespace
      • Overview
      • diagnose
      • generate-root
      • init
      • key-status
      • members
      • migrate
      • raft
      • rekey
      • rotate
      • seal
      • step-down
      • unseal
      • usage
    • path-help
      • Overview
      • deregister
      • info
      • list
      • register
      • reload
      • Overview
      • delete
      • fmt
      • list
      • read
      • write
    • read
      • Overview
      • disable
      • enable
      • list
      • move
      • tune
    • server
    • ssh
    • status
      • Overview
      • capabilities
      • create
      • lookup
      • renew
      • revoke
    • unwrap
    • version
    • version-history
    • write
    • Token Helpers
    • Overview
      • Overview
        • Overview
        • AliCloud
        • AppRole
        • AWS
        • Azure
        • Cert
        • CF
        • GCP
        • JWT
        • Kerberos
        • Kubernetes
        • Overview
        • File
      • Overview
        • Overview
        • Kubernetes
    • Templates
    • Windows service

    • Overview
    • Active Directory
    • AliCloud
    • AWS
    • Azure
    • Consul
    • Cubbyhole
      • Overview
      • Cassandra
      • Couchbase
      • Elasticsearch
      • HanaDB
      • IBM Db2
      • InfluxDB
      • MongoDB
      • MongoDB Atlas
      • MSSQL
      • MySQL/MariaDB
      • Oracle
      • PostgreSQL
      • Redshift
      • Snowflake
      • Custom
    • Google Cloud
    • Google Cloud KMS
      • Overview
      • Azure Key Vault
      • AWS KMS
      • GCP Cloud KMS
    • KMIP ENTERPRISE
      • Overview
      • K/V Version 1
      • K/V Version 2
      • Overview
      • Identity Tokens
      • OIDC Identity Provider
    • MongoDB Atlas
    • Nomad
    • OpenLDAP
    • PKI (Certificates)
    • RabbitMQ
      • Overview
      • Signed Certificates
      • SSH OTP
      • Dynamic Key
    • Terraform Cloud
    • TOTP
      • Overview
      • FF3-1 Tweak Usage
      • Tokenization Transform ENTERPRISE
    • Transit
    • Venafi (Certificates)
    • Overview
    • AppRole
    • AliCloud
    • AWS
    • Azure
    • Cloud Foundry
    • GitHub
    • Google Cloud
      • Overview
      • OIDC Providers
    • Kerberos
    • Kubernetes
    • LDAP
      • Overview
      • FAQ
    • Oracle Cloud Infrastructure
    • Okta
    • RADIUS
    • TLS Certificates
    • Tokens
    • Username & Password

    • App ID DEPRECATED
    • MFA LEGACY / UNSUPPORTED
    • Overview
    • File
    • Syslog
    • Socket
    • Overview
    • Plugin Architecture
    • Plugin Development
    • Plugin Management
    • Plugin Portal
  • Vault Integration Program
  • Troubleshoot

    • Overview
      • Overview
      • Agent Injector vs. Vault CSI Provider
        • Overview
        • Running Vault
        • Enterprise Licensing
        • Running Vault on OpenShift
        • Configuration
          • Overview
          • Development
          • Standalone with Load Balanced UI
          • Standalone with TLS
          • Standalone with Audit Storage
          • External Vault
          • Using Kubernetes Auth Method
          • HA Cluster with Consul
          • HA Cluster with Raft
          • HA Enterprise Cluster with Raft
          • HA Enterprise DR Clusters with Raft
          • HA Enterprise Performance Clusters with Raft
          • Vault Agent Injector TLS Configuration
          • Vault Agent Injector TLS with Cert-Manager
        • Overview
        • Annotations
        • Installation
        • Examples
        • Overview
        • Installation
        • Configurations
        • Examples
      • Overview
      • Vault Lambda Extension
      • Running Vault
      • Overview
      • Installation
      • Configuration
      • Troubleshooting
      • Overview
      • Installation
      • Troubleshooting

    • Overview
    • Upgrade Plugins
    • Upgrade to 1.10.x
    • Upgrade to 1.9.x
    • Upgrade to 1.8.x
    • Upgrade to 1.7.x
    • Upgrade to 1.6.3
    • Upgrade to 1.6.2
    • Upgrade to 1.6.1
    • Upgrade to 1.6.0
    • Upgrade to 1.5.3
    • Upgrade to 1.5.2
    • Upgrade to 1.5.1
    • Upgrade to 1.5.0
    • Upgrade to 1.4.6
    • Upgrade to 1.4.5
    • Upgrade to 1.4.4
    • Upgrade to 1.4.1
    • Upgrade to 1.4.0
    • Upgrade to 1.3.10
    • Upgrade to 1.3.9
    • Upgrade to 1.3.8
    • Upgrade to 1.3.5
    • Upgrade to 1.3.4
    • Upgrade to 1.3.3
    • Upgrade to 1.3.2
    • Upgrade to 1.3.0
    • Upgrade to 1.2.7
    • Upgrade to 1.2.6
    • Upgrade to 1.2.5
    • Upgrade to 1.2.4
    • Upgrade to 1.2.1
    • Upgrade to 1.2.0
    • Upgrade to 1.1.2
    • Upgrade to 1.1.1
    • Upgrade to 1.1.0
    • Upgrade to 1.0.0
    • Upgrade to 0.11.6
    • Upgrade to 0.11.2
    • Upgrade to 0.11.0
    • Upgrade to 0.10.4
    • Upgrade to 0.10.2
    • Upgrade to 0.10.0
    • Upgrade to 0.9.6
    • Upgrade to 0.9.3
    • Upgrade to 0.9.2
    • Upgrade to 0.9.1
    • Upgrade to 0.9.0
    • Upgrade to 0.8.0
    • Upgrade to 0.7.0
    • Upgrade to 0.6.4
    • Upgrade to 0.6.3
    • Upgrade to 0.6.2
    • Upgrade to 0.6.1
    • Upgrade to 0.6.0
    • Upgrade to 0.5.1
    • Upgrade to 0.5.0

    • Overview
    • 1.10.0
    • 1.9.0
    • 1.8.0
    • 1.7.0
    • 1.6.0
    • 1.5.0

    • Overview
    • FAQ

    • Overview
    • Feature Deprecation Notice and Plans
    • License
    • Client Count
    • Login MFA
    • Server Side Consistent Token

  • Glossary

    • Overview
      • Overview
      • Autoloading
      • FAQ
    • Replication
      • Overview
      • Behavioral Changes
      • Security
    • Automated Integrated Storage Snapshots
    • Lease Count Quotas
    • Entropy Augmentation
    • Seal Wrap / FIPS 140-2
    • Namespaces
    • Performance Standbys
    • Eventual Consistency
    • Control Groups
    • Managed Keys
      • Overview
      • Duo MFA
      • Okta MFA
      • PingID MFA
      • TOTP MFA
      • Overview
      • Examples
      • Properties
    • HCP Vault
Type '/' to Search

»AppRole Auth Method

The approle auth method allows machines or apps to authenticate with Vault-defined roles. The open design of AppRole enables a varied set of workflows and configurations to handle large numbers of apps. This auth method is oriented to automated workflows (machines and services), and is less useful for human operators.

An "AppRole" represents a set of Vault policies and login constraints that must be met to receive a token with those policies. The scope can be as narrow or broad as desired. An AppRole can be created for a particular machine, or even a particular user on that machine, or a service spread across machines. The credentials required for successful login depend upon the constraints set on the AppRole associated with the credentials.

»Authentication

»Via the CLI

The default path is /approle. If this auth method was enabled at a different path, specify auth/my-path/login instead.

$ vault write auth/approle/login \
    role_id=db02de05-fa39-4855-059b-67221c5c2f63 \
    secret_id=6a174c20-f6de-a53c-74d2-6018fcceff64

Key                Value
---                -----
token              65b74ffd-842c-fd43-1386-f7d7006e520a
token_accessor     3c29bc22-5c72-11a6-f778-2bc8f48cea0e
token_duration     20m0s
token_renewable    true
token_policies     [default]
$ vault write auth/approle/login \
    role_id=db02de05-fa39-4855-059b-67221c5c2f63 \
    secret_id=6a174c20-f6de-a53c-74d2-6018fcceff64

Key                Value
---                -----
token              65b74ffd-842c-fd43-1386-f7d7006e520a
token_accessor     3c29bc22-5c72-11a6-f778-2bc8f48cea0e
token_duration     20m0s
token_renewable    true
token_policies     [default]

»Via the API

The default endpoint is auth/approle/login. If this auth method was enabled at a different path, use that value instead of approle.

$ curl \
    --request POST \
    --data '{"role_id":"988a9df-...","secret_id":"37b74931..."}' \
    http://127.0.0.1:8200/v1/auth/approle/login
$ curl \
    --request POST \
    --data '{"role_id":"988a9df-...","secret_id":"37b74931..."}' \
    http://127.0.0.1:8200/v1/auth/approle/login

The response will contain the token at auth.client_token:

{
  "auth": {
    "renewable": true,
    "lease_duration": 2764800,
    "metadata": {},
    "policies": ["default", "dev-policy", "test-policy"],
    "accessor": "5d7fb475-07cb-4060-c2de-1ca3fcbf0c56",
    "client_token": "98a4c7ab-b1fe-361b-ba0b-e307aacfd587"
  }
}
{
  "auth": {
    "renewable": true,
    "lease_duration": 2764800,
    "metadata": {},
    "policies": ["default", "dev-policy", "test-policy"],
    "accessor": "5d7fb475-07cb-4060-c2de-1ca3fcbf0c56",
    "client_token": "98a4c7ab-b1fe-361b-ba0b-e307aacfd587"
  }
}

Application Integration: See the Code Example section for a code snippet demonstrating the authentication with Vault using the AppRole auth method.

»Configuration

Auth methods must be configured in advance before users or machines can authenticate. These steps are usually completed by an operator or configuration management tool.

»Via the CLI

  1. Enable the AppRole auth method:

    $ vault auth enable approle
    
    $ vault auth enable approle
    
  2. Create a named role:

    $ vault write auth/approle/role/my-role \
        secret_id_ttl=10m \
        token_num_uses=10 \
        token_ttl=20m \
        token_max_ttl=30m \
        secret_id_num_uses=40
    
    $ vault write auth/approle/role/my-role \
        secret_id_ttl=10m \
        token_num_uses=10 \
        token_ttl=20m \
        token_max_ttl=30m \
        secret_id_num_uses=40
    

Note: If the token issued by your approle needs the ability to create child tokens, you will need to set token_num_uses to 0.

For the complete list of configuration options, please see the API documentation.

  1. Fetch the RoleID of the AppRole:

    $ vault read auth/approle/role/my-role/role-id
    role_id     db02de05-fa39-4855-059b-67221c5c2f63
    
    $ vault read auth/approle/role/my-role/role-id
    role_id     db02de05-fa39-4855-059b-67221c5c2f63
    
  2. Get a SecretID issued against the AppRole:

    $ vault write -f auth/approle/role/my-role/secret-id
    secret_id               6a174c20-f6de-a53c-74d2-6018fcceff64
    secret_id_accessor      c454f7e5-996e-7230-6074-6ef26b7bcf86
    secret_id_ttl           10m
    
    $ vault write -f auth/approle/role/my-role/secret-id
    secret_id               6a174c20-f6de-a53c-74d2-6018fcceff64
    secret_id_accessor      c454f7e5-996e-7230-6074-6ef26b7bcf86
    secret_id_ttl           10m
    

»Via the API

  1. Enable the AppRole auth method:

    $ curl \
        --header "X-Vault-Token: ..." \
        --request POST \
        --data '{"type": "approle"}' \
        http://127.0.0.1:8200/v1/sys/auth/approle
    
    $ curl \
        --header "X-Vault-Token: ..." \
        --request POST \
        --data '{"type": "approle"}' \
        http://127.0.0.1:8200/v1/sys/auth/approle
    
  2. Create an AppRole with desired set of policies:

    $ curl \
        --header "X-Vault-Token: ..." \
        --request POST \
        --data '{"policies": "dev-policy,test-policy"}' \
        http://127.0.0.1:8200/v1/auth/approle/role/my-role
    
    $ curl \
        --header "X-Vault-Token: ..." \
        --request POST \
        --data '{"policies": "dev-policy,test-policy"}' \
        http://127.0.0.1:8200/v1/auth/approle/role/my-role
    
  3. Fetch the identifier of the role:

    $ curl \
        --header "X-Vault-Token: ..." \
        http://127.0.0.1:8200/v1/auth/approle/role/my-role/role-id
    
    $ curl \
        --header "X-Vault-Token: ..." \
        http://127.0.0.1:8200/v1/auth/approle/role/my-role/role-id
    

    The response will look like:

    {
      "data": {
        "role_id": "988a9dfd-ea69-4a53-6cb6-9d6b86474bba"
      }
    }
    
    {
      "data": {
        "role_id": "988a9dfd-ea69-4a53-6cb6-9d6b86474bba"
      }
    }
    
  4. Create a new secret identifier under the role:

    $ curl \
        --header "X-Vault-Token: ..." \
        --request POST \
         http://127.0.0.1:8200/v1/auth/approle/role/my-role/secret-id
    
    $ curl \
        --header "X-Vault-Token: ..." \
        --request POST \
         http://127.0.0.1:8200/v1/auth/approle/role/my-role/secret-id
    

    The response will look like:

    {
      "data": {
        "secret_id_accessor": "45946873-1d96-a9d4-678c-9229f74386a5",
        "secret_id": "37b74931-c4cd-d49a-9246-ccc62d682a25",
        "secret_id_ttl": 600
      }
    }
    
    {
      "data": {
        "secret_id_accessor": "45946873-1d96-a9d4-678c-9229f74386a5",
        "secret_id": "37b74931-c4cd-d49a-9246-ccc62d682a25",
        "secret_id_ttl": 600
      }
    }
    

»Credentials/Constraints

»RoleID

RoleID is an identifier that selects the AppRole against which the other credentials are evaluated. When authenticating against this auth method's login endpoint, the RoleID is a required argument (via role_id) at all times. By default, RoleIDs are unique UUIDs, which allow them to serve as secondary secrets to the other credential information. However, they can be set to particular values to match introspected information by the client (for instance, the client's domain name).

»SecretID

SecretID is a credential that is required by default for any login (via secret_id) and is intended to always be secret. (For advanced usage, requiring a SecretID can be disabled via an AppRole's bind_secret_id parameter, allowing machines with only knowledge of the RoleID, or matching other set constraints, to fetch a token). SecretIDs can be created against an AppRole either via generation of a 128-bit purely random UUID by the role itself (Pull mode) or via specific, custom values (Push mode). Similarly to tokens, SecretIDs have properties like usage-limit, TTLs and expirations.

»Pull And Push SecretID Modes

If the SecretID used for login is fetched from an AppRole, this is operating in Pull mode. If a "custom" SecretID is set against an AppRole by the client, it is referred to as a Push mode. Push mode mimics the behavior of the deprecated App-ID auth method; however, in most cases Pull mode is the better approach. The reason is that Push mode requires some other system to have knowledge of the full set of client credentials (RoleID and SecretID) in order to create the entry, even if these are then distributed via different paths. However, in Pull mode, even though the RoleID must be known in order to distribute it to the client, the SecretID can be kept confidential from all parties except for the final authenticating client by using Response Wrapping.

Push mode is available for App-ID workflow compatibility, which in some specific cases is preferable, but in most cases Pull mode is more secure and should be preferred.

»Further Constraints

role_id is a required credential at the login endpoint. AppRole pointed to by the role_id will have constraints set on it. This dictates other required credentials for login. The bind_secret_id constraint requires secret_id to be presented at the login endpoint. Going forward, this auth method can support more constraint parameters to support varied set of Apps. Some constraints will not require a credential, but still enforce constraints for login. For example, secret_id_bound_cidrs will only allow logins coming from IP addresses belonging to configured CIDR blocks on the AppRole.

»Tutorial

Refer to the AppRole Pull Authentication tutorial to learn how to use the AppRole method to generate tokens for machines or apps.

»API

The AppRole auth method has a full HTTP API. Please see the AppRole API for more details.

»Code Example

The following example demonstrates AppRole authentication with response wrapping.

Go
  • Go
  • C#
package main

import (
    "context"
    "fmt"
    "os"

    vault "github.com/hashicorp/vault/api"
    auth "github.com/hashicorp/vault/api-docs/auth/approle"
)

// Fetches a key-value secret (kv-v2) after authenticating via AppRole.
func getSecretWithAppRole() (string, error) {
    config := vault.DefaultConfig() // modify for more granular configuration

    client, err := vault.NewClient(config)
    if err != nil {
        return "", fmt.Errorf("unable to initialize Vault client: %w", err)
    }

    // A combination of a Role ID and Secret ID is required to log in to Vault
    // with an AppRole.
    // First, let's get the role ID given to us by our Vault administrator.
    roleID := os.Getenv("APPROLE_ROLE_ID")
    if roleID == "" {
        return "", fmt.Errorf("no role ID was provided in APPROLE_ROLE_ID env var")
    }

    // The Secret ID is a value that needs to be protected, so instead of the
    // app having knowledge of the secret ID directly, we have a trusted orchestrator (https://learn.hashicorp.com/tutorials/vault/secure-introduction?in=vault/app-integration#trusted-orchestrator)
    // give the app access to a short-lived response-wrapping token (https://www.vaultproject.io/docs/concepts/response-wrapping).
    // Read more at: https://learn.hashicorp.com/tutorials/vault/approle-best-practices?in=vault/auth-methods#secretid-delivery-best-practices
    secretID := &auth.SecretID{FromFile: "path/to/wrapping-token"}

    appRoleAuth, err := auth.NewAppRoleAuth(
        roleID,
        secretID,
        auth.WithWrappingToken(), // Only required if the secret ID is response-wrapped.
    )
    if err != nil {
        return "", fmt.Errorf("unable to initialize AppRole auth method: %w", err)
    }

    authInfo, err := client.Auth().Login(context.TODO(), appRoleAuth)
    if err != nil {
        return "", fmt.Errorf("unable to login to AppRole auth method: %w", err)
    }
    if authInfo == nil {
        return "", fmt.Errorf("no auth info was returned after login")
    }

    // get secret
    secret, err := client.Logical().Read("kv-v2/data/creds")
    if err != nil {
        return "", fmt.Errorf("unable to read secret: %w", err)
    }

    data, ok := secret.Data["data"].(map[string]interface{})
    if !ok {
        return "", fmt.Errorf("data type assertion failed: %T %#v", secret.Data["data"], secret.Data["data"])
    }

    // data map can contain more than one key-value pair,
    // in this case we're just grabbing one of them
    key := "password"
    value, ok := data[key].(string)
    if !ok {
        return "", fmt.Errorf("value type assertion failed: %T %#v", data[key], data[key])
    }

    return value, nil
}
package main

import (
    "context"
    "fmt"
    "os"

    vault "github.com/hashicorp/vault/api"
    auth "github.com/hashicorp/vault/api-docs/auth/approle"
)

// Fetches a key-value secret (kv-v2) after authenticating via AppRole.
func getSecretWithAppRole() (string, error) {
    config := vault.DefaultConfig() // modify for more granular configuration

    client, err := vault.NewClient(config)
    if err != nil {
        return "", fmt.Errorf("unable to initialize Vault client: %w", err)
    }

    // A combination of a Role ID and Secret ID is required to log in to Vault
    // with an AppRole.
    // First, let's get the role ID given to us by our Vault administrator.
    roleID := os.Getenv("APPROLE_ROLE_ID")
    if roleID == "" {
        return "", fmt.Errorf("no role ID was provided in APPROLE_ROLE_ID env var")
    }

    // The Secret ID is a value that needs to be protected, so instead of the
    // app having knowledge of the secret ID directly, we have a trusted orchestrator (https://learn.hashicorp.com/tutorials/vault/secure-introduction?in=vault/app-integration#trusted-orchestrator)
    // give the app access to a short-lived response-wrapping token (https://www.vaultproject.io/docs/concepts/response-wrapping).
    // Read more at: https://learn.hashicorp.com/tutorials/vault/approle-best-practices?in=vault/auth-methods#secretid-delivery-best-practices
    secretID := &auth.SecretID{FromFile: "path/to/wrapping-token"}

    appRoleAuth, err := auth.NewAppRoleAuth(
        roleID,
        secretID,
        auth.WithWrappingToken(), // Only required if the secret ID is response-wrapped.
    )
    if err != nil {
        return "", fmt.Errorf("unable to initialize AppRole auth method: %w", err)
    }

    authInfo, err := client.Auth().Login(context.TODO(), appRoleAuth)
    if err != nil {
        return "", fmt.Errorf("unable to login to AppRole auth method: %w", err)
    }
    if authInfo == nil {
        return "", fmt.Errorf("no auth info was returned after login")
    }

    // get secret
    secret, err := client.Logical().Read("kv-v2/data/creds")
    if err != nil {
        return "", fmt.Errorf("unable to read secret: %w", err)
    }

    data, ok := secret.Data["data"].(map[string]interface{})
    if !ok {
        return "", fmt.Errorf("data type assertion failed: %T %#v", secret.Data["data"], secret.Data["data"])
    }

    // data map can contain more than one key-value pair,
    // in this case we're just grabbing one of them
    key := "password"
    value, ok := data[key].(string)
    if !ok {
        return "", fmt.Errorf("value type assertion failed: %T %#v", data[key], data[key])
    }

    return value, nil
}
using System;
using System.Collections.Generic;
using System.IO;
using VaultSharp;
using VaultSharp.V1.AuthMethods;
using VaultSharp.V1.AuthMethods.AppRole;
using VaultSharp.V1.AuthMethods.Token;
using VaultSharp.V1.Commons;

namespace Examples
{
    public class ApproleAuthExample
    {
        const string DefaultTokenPath = "../../../path/to/wrapping-token";

        /// <summary>
        /// Fetches a key-value secret (kv-v2) after authenticating to Vault via AppRole authentication
        /// </summary>
        public string GetSecretWithAppRole()
        {
            // A combination of a Role ID and Secret ID is required to log in to Vault with an AppRole.
            // The Secret ID is a value that needs to be protected, so instead of the app having knowledge of the secret ID directly,
            // we have a trusted orchestrator (https://learn.hashicorp.com/tutorials/vault/secure-introduction?in=vault/app-integration#trusted-orchestrator)
            // give the app access to a short-lived response-wrapping token (https://www.vaultproject.io/docs/concepts/response-wrapping).
            // Read more at: https://learn.hashicorp.com/tutorials/vault/approle-best-practices?in=vault/auth-methods#secretid-delivery-best-practices
            var vaultAddr = Environment.GetEnvironmentVariable("VAULT_ADDR");
            if(String.IsNullOrEmpty(vaultAddr))
            {
                throw new System.ArgumentNullException("Vault Address");
            }

            var roleId = Environment.GetEnvironmentVariable("APPROLE_ROLE_ID");
            if(String.IsNullOrEmpty(roleId))
            {
                throw new System.ArgumentNullException("AppRole Role Id");
            }
            // Get the path to wrapping token or fall back on default path
            string pathToToken = !String.IsNullOrEmpty(Environment.GetEnvironmentVariable("WRAPPING_TOKEN_PATH")) ? Environment.GetEnvironmentVariable("WRAPPING_TOKEN_PATH") : DefaultTokenPath;
            string wrappingToken = File.ReadAllText(pathToToken); // placed here by a trusted orchestrator

            // We need to create two VaultClient objects for authenticating via AppRole. The first is for
            // using the unwrap utility. We need to initialize the client with the wrapping token.
            IAuthMethodInfo wrappedTokenAuthMethod = new TokenAuthMethodInfo(wrappingToken);
            var vaultClientSettingsForUnwrapping = new VaultClientSettings(vaultAddr, wrappedTokenAuthMethod);

            IVaultClient vaultClientForUnwrapping = new VaultClient(vaultClientSettingsForUnwrapping);

            // We pass null here instead of the wrapping token to avoid depleting its single usage
            // given that we already initialized our client with the wrapping token
            Secret<Dictionary<string, object>> secretIdData =  vaultClientForUnwrapping.V1.System
                .UnwrapWrappedResponseDataAsync<Dictionary<string, object>>(null).Result;

            var secretId = secretIdData.Data["secret_id"]; // Grab the secret_id

            // We create a second VaultClient and initialize it with the AppRole auth method and our new credentials.
            IAuthMethodInfo authMethod = new AppRoleAuthMethodInfo(roleId, secretId.ToString());
            var vaultClientSettings = new VaultClientSettings(vaultAddr, authMethod);

            IVaultClient vaultClient = new VaultClient(vaultClientSettings);

            // We can retrieve the secret from VaultClient
            Secret<SecretData> kv2Secret = null;
            kv2Secret = vaultClient.V1.Secrets.KeyValue.V2.ReadSecretAsync(path: "/creds").Result;

            var password = kv2Secret.Data.Data["password"];

            return password.ToString();
        }
    }
}
using System;
using System.Collections.Generic;
using System.IO;
using VaultSharp;
using VaultSharp.V1.AuthMethods;
using VaultSharp.V1.AuthMethods.AppRole;
using VaultSharp.V1.AuthMethods.Token;
using VaultSharp.V1.Commons;

namespace Examples
{
    public class ApproleAuthExample
    {
        const string DefaultTokenPath = "../../../path/to/wrapping-token";

        /// <summary>
        /// Fetches a key-value secret (kv-v2) after authenticating to Vault via AppRole authentication
        /// </summary>
        public string GetSecretWithAppRole()
        {
            // A combination of a Role ID and Secret ID is required to log in to Vault with an AppRole.
            // The Secret ID is a value that needs to be protected, so instead of the app having knowledge of the secret ID directly,
            // we have a trusted orchestrator (https://learn.hashicorp.com/tutorials/vault/secure-introduction?in=vault/app-integration#trusted-orchestrator)
            // give the app access to a short-lived response-wrapping token (https://www.vaultproject.io/docs/concepts/response-wrapping).
            // Read more at: https://learn.hashicorp.com/tutorials/vault/approle-best-practices?in=vault/auth-methods#secretid-delivery-best-practices
            var vaultAddr = Environment.GetEnvironmentVariable("VAULT_ADDR");
            if(String.IsNullOrEmpty(vaultAddr))
            {
                throw new System.ArgumentNullException("Vault Address");
            }

            var roleId = Environment.GetEnvironmentVariable("APPROLE_ROLE_ID");
            if(String.IsNullOrEmpty(roleId))
            {
                throw new System.ArgumentNullException("AppRole Role Id");
            }
            // Get the path to wrapping token or fall back on default path
            string pathToToken = !String.IsNullOrEmpty(Environment.GetEnvironmentVariable("WRAPPING_TOKEN_PATH")) ? Environment.GetEnvironmentVariable("WRAPPING_TOKEN_PATH") : DefaultTokenPath;
            string wrappingToken = File.ReadAllText(pathToToken); // placed here by a trusted orchestrator

            // We need to create two VaultClient objects for authenticating via AppRole. The first is for
            // using the unwrap utility. We need to initialize the client with the wrapping token.
            IAuthMethodInfo wrappedTokenAuthMethod = new TokenAuthMethodInfo(wrappingToken);
            var vaultClientSettingsForUnwrapping = new VaultClientSettings(vaultAddr, wrappedTokenAuthMethod);

            IVaultClient vaultClientForUnwrapping = new VaultClient(vaultClientSettingsForUnwrapping);

            // We pass null here instead of the wrapping token to avoid depleting its single usage
            // given that we already initialized our client with the wrapping token
            Secret<Dictionary<string, object>> secretIdData =  vaultClientForUnwrapping.V1.System
                .UnwrapWrappedResponseDataAsync<Dictionary<string, object>>(null).Result;

            var secretId = secretIdData.Data["secret_id"]; // Grab the secret_id

            // We create a second VaultClient and initialize it with the AppRole auth method and our new credentials.
            IAuthMethodInfo authMethod = new AppRoleAuthMethodInfo(roleId, secretId.ToString());
            var vaultClientSettings = new VaultClientSettings(vaultAddr, authMethod);

            IVaultClient vaultClient = new VaultClient(vaultClientSettings);

            // We can retrieve the secret from VaultClient
            Secret<SecretData> kv2Secret = null;
            kv2Secret = vaultClient.V1.Secrets.KeyValue.V2.ReadSecretAsync(path: "/creds").Result;

            var password = kv2Secret.Data.Data["password"];

            return password.ToString();
        }
    }
}
github logoEdit this page
DocsAPILearnCommunityPrivacySecurityPress KitConsent Manager