Skip to content

Commit

Permalink
Allow custom auth backend mount point
Browse files Browse the repository at this point in the history
Signed-off-by: Dave Henderson <dhenderson@gmail.com>
  • Loading branch information
hairyhenderson committed Mar 11, 2017
1 parent 65c4abc commit b26acb7
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 51 deletions.
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -577,9 +577,13 @@ The special `vault://` URL scheme can be used to retrieve data from [Hashicorp
Vault](https://vaultproject.io). To use this, you must put the Vault server's
URL in the `$VAULT_ADDR` environment variable.

Currently, the [`app-id`](https://www.vaultproject.io/docs/auth/app-id.html)
auth backend is supported, as well as Vault tokens obtained through external
means.
This table describes the currently-supported authentication mechanisms and how to use them, in order of precedence:

| auth backend | configuration |
| ---: |--|
| [`app-id`](https://www.vaultproject.io/docs/auth/app-id.html) | Environment variables `$VAULT_APP_ID` and `$VAULT_USER_ID` must be set to the appropriate values.<br/> If the backend is mounted to a different location, set `$VAULT_AUTH_APP_ID_MOUNT`. |
| [`github`](https://www.vaultproject.io/docs/auth/github.html) | Environment variable `$VAULT_AUTH_GITHUB_TOKEN` must be set to an appropriate value.<br/> If the backend is mounted to a different location, set `$VAULT_AUTH_GITHUB_MOUNT`. |
| [`token`](https://www.vaultproject.io/docs/auth/token.html) | Determined from either the `$VAULT_TOKEN` environment variable, or read from the file `~/.vault-token` |

To use a Vault datasource with a single secret, just use a URL of
`vault:///secret/mysecret`. Note the 3 `/`s - the host portion of the URL is left
Expand Down
19 changes: 12 additions & 7 deletions vault/app-id_strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
type AppIDAuthStrategy struct {
AppID string `json:"app_id"`
UserID string `json:"user_id"`
Mount string `json:"-"`
hc *http.Client
}

Expand All @@ -22,8 +23,12 @@ type AppIDAuthStrategy struct {
func NewAppIDAuthStrategy() *AppIDAuthStrategy {
appID := os.Getenv("VAULT_APP_ID")
userID := os.Getenv("VAULT_USER_ID")
mount := os.Getenv("VAULT_AUTH_APP_ID_MOUNT")
if mount == "" {
mount = "app-id"
}
if appID != "" && userID != "" {
return &AppIDAuthStrategy{appID, userID, nil}
return &AppIDAuthStrategy{appID, userID, mount, nil}
}
return nil
}
Expand Down Expand Up @@ -54,12 +59,12 @@ func (a *AppIDAuthStrategy) GetToken(addr *url.URL) (string, error) {

u := &url.URL{}
*u = *addr
u.Path = "/v1/auth/app-id/login"
u.Path = "/v1/auth/" + a.Mount + "/login"
res, err := requestAndFollow(a, "POST", u, buf.Bytes())
if err != nil {
return "", err
}
response := &AuthResponse{}
response := &AppIDAuthResponse{}
err = json.NewDecoder(res.Body).Decode(response)
res.Body.Close()
if err != nil {
Expand All @@ -78,11 +83,11 @@ func (a *AppIDAuthStrategy) Revokable() bool {
}

func (a *AppIDAuthStrategy) String() string {
return fmt.Sprintf("app-id: %s, user-id: %s", a.AppID, a.UserID)
return fmt.Sprintf("app-id: %s, user-id: %s, mount: %s", a.AppID, a.UserID, a.Mount)
}

// AuthResponse - the Auth response from /v1/auth/app-id/login
type AuthResponse struct {
// AppIDAuthResponse - the Auth response from /v1/auth/app-id/login
type AppIDAuthResponse struct {
Auth struct {
ClientToken string `json:"client_token"`
LeaseDuration int64 `json:"lease_duration"`
Expand All @@ -95,7 +100,7 @@ type AuthResponse struct {
} `json:"auth"`
}

func (a *AuthResponse) String() string {
func (a *AppIDAuthResponse) String() string {
buf := new(bytes.Buffer)
json.NewEncoder(buf).Encode(&a)
return string(buf.Bytes())
Expand Down
45 changes: 4 additions & 41 deletions vault/app-id_strategy_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package vault

import (
"fmt"
"net/http"
"net/http/httptest"
"net/url"
"os"
"testing"
Expand Down Expand Up @@ -36,7 +33,7 @@ func TestGetToken_AppIDErrorsGivenNetworkError(t *testing.T) {

vaultURL, _ := url.Parse("http://vault:8200")

auth := &AppIDAuthStrategy{"foo", "bar", client}
auth := &AppIDAuthStrategy{"foo", "bar", "app-id", client}
_, err := auth.GetToken(vaultURL)
assert.Error(t, err)
}
Expand All @@ -47,7 +44,7 @@ func TestGetToken_AppIDErrorsGivenHTTPErrorStatus(t *testing.T) {

vaultURL, _ := url.Parse("http://vault:8200")

auth := &AppIDAuthStrategy{"foo", "bar", client}
auth := &AppIDAuthStrategy{"foo", "bar", "app-id", client}
_, err := auth.GetToken(vaultURL)
assert.Error(t, err)
}
Expand All @@ -58,7 +55,7 @@ func TestGetToken_AppIDErrorsGivenBadJSON(t *testing.T) {

vaultURL, _ := url.Parse("http://vault:8200")

auth := &AppIDAuthStrategy{"foo", "bar", client}
auth := &AppIDAuthStrategy{"foo", "bar", "app-id", client}
_, err := auth.GetToken(vaultURL)
assert.Error(t, err)
}
Expand All @@ -69,43 +66,9 @@ func TestGetToken_AppID(t *testing.T) {

vaultURL, _ := url.Parse("http://vault:8200")

auth := &AppIDAuthStrategy{"foo", "bar", client}
auth := &AppIDAuthStrategy{"foo", "bar", "app-id", client}
token, err := auth.GetToken(vaultURL)
assert.NoError(t, err)

assert.Equal(t, "baz", token)
}

func setupHTTP(code int, mimetype string, body string) (*httptest.Server, *http.Client) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", mimetype)
w.WriteHeader(code)
fmt.Fprintln(w, body)
}))

client := &http.Client{
Transport: &http.Transport{
Proxy: func(req *http.Request) (*url.URL, error) {
return url.Parse(server.URL)
},
},
}

return server, client
}

func setupErrorHTTP() (*httptest.Server, *http.Client) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
panic("boo")
}))

client := &http.Client{
Transport: &http.Transport{
Proxy: func(req *http.Request) (*url.URL, error) {
return url.Parse(server.URL)
},
},
}

return server, client
}
42 changes: 42 additions & 0 deletions vault/testutils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package vault

import (
"fmt"
"net/http"
"net/http/httptest"
"net/url"
)

func setupHTTP(code int, mimetype string, body string) (*httptest.Server, *http.Client) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", mimetype)
w.WriteHeader(code)
fmt.Fprintln(w, body)
}))

client := &http.Client{
Transport: &http.Transport{
Proxy: func(req *http.Request) (*url.URL, error) {
return url.Parse(server.URL)
},
},
}

return server, client
}

func setupErrorHTTP() (*httptest.Server, *http.Client) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
panic("boo")
}))

client := &http.Client{
Transport: &http.Transport{
Proxy: func(req *http.Request) (*url.URL, error) {
return url.Parse(server.URL)
},
},
}

return server, client
}

0 comments on commit b26acb7

Please sign in to comment.