Merge branch 'master' of https://github.com/hashicorp/vault
This commit is contained in:
commit
475df43c59
|
@ -54,7 +54,7 @@ that can be enabled (see
|
|||
[authentication](#reference/authentication)).
|
||||
|
||||
Authentication is done with the login endpoint. The login endpoint
|
||||
returns an access token that is set as the `token` cookie.
|
||||
returns an access token that is set as the `X-Vault-Token` header.
|
||||
|
||||
## Help
|
||||
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/vault/http"
|
||||
"github.com/hashicorp/vault/vault"
|
||||
)
|
||||
|
||||
func TestAuthTokenCreate(t *testing.T) {
|
||||
core, _, token := vault.TestCoreUnsealed(t)
|
||||
ln, addr := http.TestServer(t, core)
|
||||
defer ln.Close()
|
||||
|
||||
config := DefaultConfig()
|
||||
config.Address = addr
|
||||
|
||||
client, err := NewClient(config)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
client.SetToken(token)
|
||||
|
||||
secret, err := client.Auth().Token().Create(&TokenCreateRequest{
|
||||
Lease: "1h",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if secret.Auth.LeaseDuration != 3600 {
|
||||
t.Errorf("expected 1h, got %q", secret.Auth.LeaseDuration)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthTokenRenew(t *testing.T) {
|
||||
core, _, token := vault.TestCoreUnsealed(t)
|
||||
ln, addr := http.TestServer(t, core)
|
||||
defer ln.Close()
|
||||
|
||||
config := DefaultConfig()
|
||||
config.Address = addr
|
||||
|
||||
client, err := NewClient(config)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
client.SetToken(token)
|
||||
|
||||
// The default root token is not renewable, so this should not work
|
||||
_, err = client.Auth().Token().Renew(token, 0)
|
||||
if err == nil {
|
||||
t.Fatal("should not be allowed to renew root token")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "lease is not renewable") {
|
||||
t.Fatal("wrong error")
|
||||
}
|
||||
|
||||
// Create a new token that should be renewable
|
||||
secret, err := client.Auth().Token().Create(&TokenCreateRequest{
|
||||
Lease: "1h",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
client.SetToken(secret.Auth.ClientToken)
|
||||
|
||||
// Now attempt a renew with the new token
|
||||
secret, err = client.Auth().Token().Renew(secret.Auth.ClientToken, 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if secret.Auth.LeaseDuration != 3600 {
|
||||
t.Errorf("expected 1h, got %q", secret.Auth.LeaseDuration)
|
||||
}
|
||||
|
||||
if secret.Auth.Renewable != true {
|
||||
t.Error("expected lease to be renewable")
|
||||
}
|
||||
}
|
|
@ -7,10 +7,13 @@ import (
|
|||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
errRedirect = errors.New("redirect")
|
||||
errRedirect = errors.New("redirect")
|
||||
defaultHTTPClientSetup sync.Once
|
||||
defaultHTTPClient = &http.Client{}
|
||||
)
|
||||
|
||||
// Config is used to configure the creation of the client.
|
||||
|
@ -21,8 +24,8 @@ type Config struct {
|
|||
// HttpClient.
|
||||
Address string
|
||||
|
||||
// HttpClient is the HTTP client to use, which will currently always be
|
||||
// http.DefaultClient. This is used to control redirect behavior.
|
||||
// HttpClient is the HTTP client to use, which will currently always have the
|
||||
// same values as http.DefaultClient. This is used to control redirect behavior.
|
||||
HttpClient *http.Client
|
||||
}
|
||||
|
||||
|
@ -34,25 +37,7 @@ type Config struct {
|
|||
func DefaultConfig() *Config {
|
||||
config := &Config{
|
||||
Address: "https://127.0.0.1:8200",
|
||||
HttpClient: http.DefaultClient,
|
||||
}
|
||||
|
||||
// From https://github.com/michiwend/gomusicbrainz/pull/4/files
|
||||
defaultRedirectLimit := 30
|
||||
|
||||
config.HttpClient.CheckRedirect = func(req *http.Request, via []*http.Request) error {
|
||||
if len(via) > defaultRedirectLimit {
|
||||
return fmt.Errorf("%d consecutive requests(redirects)", len(via))
|
||||
}
|
||||
if len(via) == 0 {
|
||||
// No redirects
|
||||
return nil
|
||||
}
|
||||
// mutate the subsequent redirect requests with the first Header
|
||||
if token := via[0].Header.Get("X-Vault-Token"); len(token) != 0 {
|
||||
req.Header.Set("X-Vault-Token", token)
|
||||
}
|
||||
return nil
|
||||
HttpClient: defaultHTTPClient,
|
||||
}
|
||||
|
||||
if addr := os.Getenv("VAULT_ADDR"); addr != "" {
|
||||
|
@ -81,9 +66,13 @@ func NewClient(c *Config) (*Client, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// Ensure redirects are not automatically followed
|
||||
c.HttpClient.CheckRedirect = func(req *http.Request, via []*http.Request) error {
|
||||
return errRedirect
|
||||
if c.HttpClient == defaultHTTPClient {
|
||||
defaultHTTPClientSetup.Do(func() {
|
||||
// Ensure redirects are not automatically followed
|
||||
c.HttpClient.CheckRedirect = func(req *http.Request, via []*http.Request) error {
|
||||
return errRedirect
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
client := &Client{
|
||||
|
@ -105,12 +94,12 @@ func (c *Client) Token() string {
|
|||
}
|
||||
|
||||
// SetToken sets the token directly. This won't perform any auth
|
||||
// verification, it simply sets the cookie properly for future requests.
|
||||
// verification, it simply sets the token properly for future requests.
|
||||
func (c *Client) SetToken(v string) {
|
||||
c.token = v
|
||||
}
|
||||
|
||||
// ClearToken deletes the token cookie if it is set or does nothing otherwise.
|
||||
// ClearToken deletes the token if it is set or does nothing otherwise.
|
||||
func (c *Client) ClearToken() {
|
||||
c.token = ""
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ func TestClientRedirect(t *testing.T) {
|
|||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
// Set the cookie manually
|
||||
// Set the token manually
|
||||
client.SetToken("foo")
|
||||
|
||||
// Do a raw "/" request
|
||||
|
|
|
@ -109,12 +109,14 @@ func testConnState(t *testing.T, certPath, keyPath string) tls.ConnectionState {
|
|||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
conf := &tls.Config{
|
||||
listenConf := &tls.Config{
|
||||
Certificates: []tls.Certificate{cert},
|
||||
ClientAuth: tls.RequestClientCert,
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
list, err := tls.Listen("tcp", "127.0.0.1:0", conf)
|
||||
dialConf := new(tls.Config)
|
||||
*dialConf = *listenConf
|
||||
list, err := tls.Listen("tcp", "127.0.0.1:0", listenConf)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
@ -122,7 +124,7 @@ func testConnState(t *testing.T, certPath, keyPath string) tls.ConnectionState {
|
|||
|
||||
go func() {
|
||||
addr := list.Addr().String()
|
||||
conn, err := tls.Dial("tcp", addr, conf)
|
||||
conn, err := tls.Dial("tcp", addr, dialConf)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
|
|
@ -35,8 +35,8 @@ $ vault auth <token>
|
|||
|
||||
#### Via the API
|
||||
|
||||
The token is set directly as a cookie for the HTTP API. The name
|
||||
of the cookie should be "token" and the value should be the token.
|
||||
The token is set directly as a header for the HTTP API. The name
|
||||
of the header should be "X-Vault-Token" and the value should be the token.
|
||||
|
||||
## API
|
||||
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
---
|
||||
layout: "docs"
|
||||
page_title: "Environment"
|
||||
sidebar_current: "docs-commands-environment"
|
||||
description: |-
|
||||
Vault's behavior can be modified by certain environment variables.
|
||||
---
|
||||
|
||||
# Environment variables
|
||||
|
||||
The Vault CLI will read the following environment variables to set
|
||||
behavioral defaults. These can be overridden in all cases using
|
||||
command-line arguments; see the command-line help for details.
|
||||
|
||||
The following table describes them:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Variable name</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>VAULT_TOKEN</tt></td>
|
||||
<td>The Vault authentication token. If not specified, the token located in <tt>$HOME/.vault-token<tt> will be used if it exists.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>VAULT_ADDR</tt></td>
|
||||
<td>The address of the Vault server.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>VAULT_CACERT</tt></td>
|
||||
<td>Path to a PEM-encoded CA cert file to use to verify the Vault server SSL certificate.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>VAULT_CAPATH</tt></td>
|
||||
<td>Path to a directory of PEM-encoded CA cert files to verify the Vault server SSL certificate. If <tt>VAULT_CACERT</tt> is specified, its value will take precedence.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>VAULT_CLIENT_CERT</tt></td>
|
||||
<td>Path to a PEM-encoded client certificate for TLS authentication to the Vault server.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>VAULT_CLIENT_KEY</tt></td>
|
||||
<td>Path to an unencrypted PEM-encoded private key matching the client certificate.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>VAULT_SKIP_VERIFY</tt></td>
|
||||
<td>If set, do not verify Vault's presented certificate before communicating with it. Setting this variable is not recommended except during testing.</td>
|
||||
</tr>
|
||||
</table>
|
|
@ -35,8 +35,7 @@ depending on user settings.
|
|||
|
||||
Once the Vault is unsealed, every other operation requires
|
||||
a _client token_. A user may have a client token explicitly.
|
||||
The client token must be sent as the `token` cookie or the
|
||||
`X-Vault-Token` HTTP header.
|
||||
The client token must be sent as the `X-Vault-Token` HTTP header.
|
||||
|
||||
Otherwise, a client token can be retrieved via
|
||||
[authentication backends](/docs/auth/index.html).
|
||||
|
@ -46,10 +45,9 @@ login endpoints. These endpoints can be reached without any authentication,
|
|||
and are used for authentication itself. These endpoints are specific
|
||||
to each authentication backend.
|
||||
|
||||
Login endpoints for authentication backends that generate an identity
|
||||
will be sent down with a `Set-Cookie` header as well as via JSON. If you have a
|
||||
well-behaved HTTP client, then authentication information will
|
||||
automatically be saved and sent to the Vault API.
|
||||
Login endpoints for authentication backends that generate an identity will be
|
||||
sent down via JSON. The resulting token should be saved on the client or passed
|
||||
via the `X-Vault-Token` header for future requests.
|
||||
|
||||
## Reading and Writing Secrets
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ clarify what is being discussed:
|
|||
* **Client Token** - A client token is a conceptually similar to a session cookie on a web site.
|
||||
Once a user authenticates, Vault returns a client token which is used for future requests.
|
||||
The token is used by Vault to verify the identity of the client and to enforce the applicable
|
||||
ACL policies.
|
||||
ACL policies. Unlike a cookie on a web site, this token is passed via HTTP headers.
|
||||
|
||||
* **Secret** - A secret is the term for anything returned by Vault which contains confidential
|
||||
or cryptographic material. Not everything returned by Vault is a secret, for example
|
||||
|
|
|
@ -51,7 +51,6 @@ a "deploy" role:
|
|||
|
||||
```text
|
||||
$ vault write aws/roles/deploy \
|
||||
name=deploy \
|
||||
policy=@policy.json
|
||||
```
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ application to renew their credentials at least hourly, and to recycle
|
|||
them once per day.
|
||||
|
||||
The next step is to configure a role. A role is a logical name that maps
|
||||
to a policy used to generated those credentials. For example, lets create
|
||||
to a policy used to generate those credentials. For example, lets create
|
||||
a "readonly" role:
|
||||
|
||||
```
|
||||
|
|
|
@ -10,9 +10,9 @@ description: |-
|
|||
|
||||
Name: `transit`
|
||||
|
||||
The transit secret backend is used to encrypt/data in-transit. Vault doesn't
|
||||
store the data sent to the backend. It can also be viewed as "encryption as
|
||||
a service."
|
||||
The transit secret backend is used to encrypt/decrypt data in-transit. Vault
|
||||
doesn't store the data sent to the backend. It can also be viewed as "encryption
|
||||
as a service."
|
||||
|
||||
The primary use case for the transit backend is to encrypt data from
|
||||
applications while still storing that encrypted data in some primary data
|
||||
|
|
|
@ -100,7 +100,7 @@ mounted can be accessed at `auth/github`. You can use `vault path-help` to
|
|||
learn more about it.
|
||||
|
||||
With the backend enabled, we first have to configure it. For GitHub,
|
||||
we tell it what organization users must part of, and map a team to a policy:
|
||||
we tell it what organization users must be a part of, and map a team to a policy:
|
||||
|
||||
```
|
||||
$ vault write auth/github/config organization=hashicorp
|
||||
|
|
|
@ -86,6 +86,9 @@
|
|||
<li<%= sidebar_current("docs-commands-readwrite") %>>
|
||||
<a href="/docs/commands/read-write.html">Reading and Writing Data</a>
|
||||
</li>
|
||||
<li<%= sidebar_current("docs-commands-environment") %>>
|
||||
<a href="/docs/commands/environment.html">Environment Variables</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
|
Loading…
Reference in New Issue