| --- |
| layout: docs |
| page_title: Authentication |
| description: >- |
| Before performing any operation with Vault, the connecting client must be |
| authenticated. |
| --- |
| |
| # Authentication |
| |
| Authentication in Vault is the process by which user or machine supplied |
| information is verified against an internal or external system. Vault supports |
| multiple [auth methods](/vault/docs/auth) including GitHub, |
| LDAP, AppRole, and more. Each auth method has a specific use case. |
| |
| Before a client can interact with Vault, it must _authenticate_ against an |
| auth method. Upon authentication, a token is generated. This token is |
| conceptually similar to a session ID on a website. The token may have attached |
| policy, which is mapped at authentication time. This process is described in |
| detail in the [policies concepts](/vault/docs/concepts/policies) documentation. |
| |
| ## auth methods |
| |
| Vault supports a number of auth methods. Some backends are targeted |
| toward users while others are targeted toward machines. Most authentication |
| backends must be enabled before use. To enable an auth method: |
| |
| ```shell-session |
| $ vault write sys/auth/my-auth type=userpass |
| ``` |
| |
| This enables the "userpass" auth method at the path "my-auth". This |
| authentication will be accessible at the path "my-auth". Often you will see |
| authentications at the same path as their name, but this is not a requirement. |
| |
| To learn more about this authentication, use the built-in `path-help` command: |
| |
| ```shell-session |
| $ vault path-help auth/my-auth |
| # ... |
| ``` |
| |
| Vault supports multiple auth methods simultaneously, and you can even |
| mount the same type of auth method at different paths. Only one |
| authentication is required to gain access to Vault, and it is not currently |
| possible to force a user through multiple auth methods to gain |
| access, although some backends do support MFA. |
| |
| ## Tokens |
| |
| There is an [entire page dedicated to tokens](/vault/docs/concepts/tokens), |
| but it is important to understand that authentication works by verifying |
| your identity and then generating a token to associate with that identity. |
| |
| For example, even though you may authenticate using something like GitHub, |
| Vault generates a unique access token for you to use for future requests. |
| The CLI automatically attaches this token to requests, but if you're using |
| the API you'll have to do this manually. |
| |
| This token given for authentication with any backend can also be used |
| with the full set of token commands, such as creating new sub-tokens, |
| revoking tokens, and renewing tokens. This is all covered on the |
| [token concepts page](/vault/docs/concepts/tokens). |
| |
| ## Authenticating |
| |
| ### Via the CLI |
| |
| To authenticate with the CLI, `vault login` is used. This supports many |
| of the built-in auth methods. For example, with GitHub: |
| |
| ```shell-session |
| $ vault login -method=github token=<token> |
| ... |
| ``` |
| |
| After authenticating, you will be logged in. The CLI command will also |
| output your raw token. This token is used for revocation and renewal. |
| As the user logging in, the primary use case of the token is renewal, |
| covered below in the "Auth Leases" section. |
| |
| To determine what variables are needed for an auth method, |
| supply the `-method` flag without any additional arguments and help |
| will be shown. |
| |
| If you're using a method that isn't supported via the CLI, then the API |
| must be used. |
| |
| ### Via the API |
| |
| API authentication is generally used for machine authentication. Each |
| auth method implements its own login endpoint. Use the `vault path-help` |
| mechanism to find the proper endpoint. |
| |
| For example, the GitHub login endpoint is located at `auth/github/login`. |
| And to determine the arguments needed, `vault path-help auth/github/login` can |
| be used. |
| |
| ## Auth leases |
| |
| Just like secrets, identities have |
| [leases](/vault/docs/concepts/lease) associated with them. This means that |
| you must reauthenticate after the given lease period to continue accessing |
| Vault. |
| |
| To set the lease associated with an identity, reference the help for |
| the specific auth method in use. It is specific to each backend |
| how leasing is implemented. |
| |
| And just like secrets, identities can be renewed without having to |
| completely reauthenticate. Just use `vault token renew <token>` with the |
| leased token associated with your identity to renew it. |
| |
| ## Code example |
| |
| The following code snippet demonstrates how to renew auth tokens. |
| |
| <CodeTabs heading="token renewal example"> |
| |
| <CodeBlockConfig lineNumbers> |
| |
| ```go |
| package main |
| |
| import ( |
| "context" |
| "fmt" |
| "log" |
| |
| vault "github.com/hashicorp/vault/api" |
| auth "github.com/hashicorp/vault/api/auth/userpass" |
| ) |
| |
| // Once you've set the token for your Vault client, you will need to |
| // periodically renew its lease. |
| // |
| // A function like this should be run as a goroutine to avoid blocking. |
| // |
| // Production applications may also wish to be more tolerant of failures and |
| // retry rather than exiting. |
| // |
| // Additionally, enterprise Vault users should be aware that due to eventual |
| // consistency, the API may return unexpected errors when running Vault with |
| // performance standbys or performance replication, despite the client having |
| // a freshly renewed token. See https://www.vaultproject.io/docs/enterprise/consistency#vault-1-7-mitigations |
| // for several ways to mitigate this which are outside the scope of this code sample. |
| func renewToken(client *vault.Client) { |
| for { |
| vaultLoginResp, err := login(client) |
| if err != nil { |
| log.Fatalf("unable to authenticate to Vault: %v", err) |
| } |
| tokenErr := manageTokenLifecycle(client, vaultLoginResp) |
| if tokenErr != nil { |
| log.Fatalf("unable to start managing token lifecycle: %v", tokenErr) |
| } |
| } |
| } |
| |
| // Starts token lifecycle management. Returns only fatal errors as errors, |
| // otherwise returns nil so we can attempt login again. |
| func manageTokenLifecycle(client *vault.Client, token *vault.Secret) error { |
| renew := token.Auth.Renewable // You may notice a different top-level field called Renewable. That one is used for dynamic secrets renewal, not token renewal. |
| if !renew { |
| log.Printf("Token is not configured to be renewable. Re-attempting login.") |
| return nil |
| } |
| |
| watcher, err := client.NewLifetimeWatcher(&vault.LifetimeWatcherInput{ |
| Secret: token, |
| Increment: 3600, // Learn more about this optional value in https://www.vaultproject.io/docs/concepts/lease#lease-durations-and-renewal |
| }) |
| if err != nil { |
| return fmt.Errorf("unable to initialize new lifetime watcher for renewing auth token: %w", err) |
| } |
| |
| go watcher.Start() |
| defer watcher.Stop() |
| |
| for { |
| select { |
| // `DoneCh` will return if renewal fails, or if the remaining lease |
| // duration is under a built-in threshold and either renewing is not |
| // extending it or renewing is disabled. In any case, the caller |
| // needs to attempt to log in again. |
| case err := <-watcher.DoneCh(): |
| if err != nil { |
| log.Printf("Failed to renew token: %v. Re-attempting login.", err) |
| return nil |
| } |
| // This occurs once the token has reached max TTL. |
| log.Printf("Token can no longer be renewed. Re-attempting login.") |
| return nil |
| |
| // Successfully completed renewal |
| case renewal := <-watcher.RenewCh(): |
| log.Printf("Successfully renewed: %#v", renewal) |
| } |
| } |
| } |
| |
| func login(client *vault.Client) (*vault.Secret, error) { |
| // WARNING: A plaintext password like this is obviously insecure. |
| // See the hashicorp/vault-examples repo for full examples of how to securely |
| // log in to Vault using various auth methods. This function is just |
| // demonstrating the basic idea that a *vault.Secret is returned by |
| // the login call. |
| userpassAuth, err := auth.NewUserpassAuth("my-user", &auth.Password{FromString: "my-password"}) |
| if err != nil { |
| return nil, fmt.Errorf("unable to initialize userpass auth method: %w", err) |
| } |
| |
| authInfo, err := client.Auth().Login(context.TODO(), userpassAuth) |
| if err != nil { |
| return nil, fmt.Errorf("unable to login to userpass auth method: %w", err) |
| } |
| if authInfo == nil { |
| return nil, fmt.Errorf("no auth info was returned after login") |
| } |
| |
| return authInfo, nil |
| } |
| ``` |
| |
| </CodeBlockConfig> |
| |
| </CodeTabs> |