Skip to content

Commit

Permalink
VAULT-6727 Role resolution for K8S Auth (#156)
Browse files Browse the repository at this point in the history
* VAULT-6727 Role resolution for K8S Auth

* VAULT-6727 use the correct file

* VAULT-6727 Add extra test
  • Loading branch information
VioletHynes authored Jul 21, 2022
1 parent 76afa58 commit ae75c7e
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 5 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ require (
github.com/hashicorp/go-uuid v1.0.2
github.com/hashicorp/go-version v1.2.0
github.com/hashicorp/vault/api v1.5.0
github.com/hashicorp/vault/sdk v0.4.1
github.com/hashicorp/vault/sdk v0.5.3
github.com/mitchellh/mapstructure v1.5.0
gopkg.in/square/go-jose.v2 v2.6.0
k8s.io/api v0.0.0-20190409092523-d687e77c8ae9
Expand Down Expand Up @@ -40,7 +40,7 @@ require (
github.com/hashicorp/go-retryablehttp v0.6.6 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 // indirect
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.4 // indirect
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect
Expand Down
7 changes: 4 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,8 @@ github.com/hashicorp/go-secure-stdlib/base62 v0.1.1/go.mod h1:EdWO6czbmthiwZ3/PU
github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 h1:cCRo8gK7oq6A2L6LICkUZ+/a5rLiRXFMf1Qd4xSwxTc=
github.com/hashicorp/go-secure-stdlib/mlock v0.1.1/go.mod h1:zq93CJChV6L9QTfGKtfBxKqD7BqqXx5O04A/ns2p5+I=
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8=
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.4 h1:hrIH/qrOTHfG9a1Jz6Z2jQf7Xe77AaD464W1fCFLwPQ=
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.4/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8=
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 h1:om4Al8Oy7kCm/B86rLCLah4Dt5Aa0Fr5rYBG60OzwHQ=
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8=
github.com/hashicorp/go-secure-stdlib/password v0.1.1/go.mod h1:9hH302QllNwu1o2TGYtSk8I8kTAN0ca1EHpwhm5Mmzo=
github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U=
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts=
Expand All @@ -242,8 +242,9 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/vault/api v1.5.0 h1:Bp6yc2bn7CWkOrVIzFT/Qurzx528bdavF3nz590eu28=
github.com/hashicorp/vault/api v1.5.0/go.mod h1:LkMdrZnWNrFaQyYYazWVn7KshilfDidgVBq6YiTq/bM=
github.com/hashicorp/vault/sdk v0.4.1 h1:3SaHOJY687jY1fnB61PtL0cOkKItphrbLmux7T92HBo=
github.com/hashicorp/vault/sdk v0.4.1/go.mod h1:aZ3fNuL5VNydQk8GcLJ2TV8YCRVvyaakYkhZRoVuhj0=
github.com/hashicorp/vault/sdk v0.5.3 h1:PWY8sq/9pRrK9vUIy75qCH2Jd8oeENAgkaa/qbhzFrs=
github.com/hashicorp/vault/sdk v0.5.3/go.mod h1:DoGraE9kKGNcVgPmTuX357Fm6WAx1Okvde8Vp3dPDoU=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
Expand Down
22 changes: 22 additions & 0 deletions path_login.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,35 @@ func pathLogin(b *kubeAuthBackend) *framework.Path {
Callbacks: map[logical.Operation]framework.OperationFunc{
logical.UpdateOperation: b.pathLogin,
logical.AliasLookaheadOperation: b.aliasLookahead,
logical.ResolveRoleOperation: b.pathResolveRole,
},

HelpSynopsis: pathLoginHelpSyn,
HelpDescription: pathLoginHelpDesc,
}
}

// pathLogin is used to resolve the role to be used from a login request
func (b *kubeAuthBackend) pathResolveRole(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
roleName, resp := b.getFieldValueStr(data, "role")
if resp != nil {
return resp, nil
}

b.l.RLock()
defer b.l.RUnlock()

role, err := b.role(ctx, req.Storage, roleName)
if err != nil {
return nil, err
}
if role == nil {
return logical.ErrorResponse(fmt.Sprintf("invalid role name %q", roleName)), nil
}

return logical.ResolveRoleResponse(roleName)
}

// pathLogin is used to authenticate to this backend
func (b *kubeAuthBackend) pathLogin(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
roleName, resp := b.getFieldValueStr(data, "role")
Expand Down
88 changes: 88 additions & 0 deletions path_login_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"encoding/pem"
"errors"
"fmt"
"github.com/hashicorp/vault/sdk/helper/tokenutil"
"net/http"
"reflect"
"strings"
Expand Down Expand Up @@ -1474,3 +1475,90 @@ func requireErrorCode(t *testing.T, err error, expectedCode int) {
t.Fatalf("wrong error code, expected %d, got %d", expectedCode, codedErr.Code())
}
}

func TestResolveRole(t *testing.T) {
b, storage := getBackend(t)
role := "testrole"

validRoleStorageEntry := &roleStorageEntry{
TokenParams: tokenutil.TokenParams{
TokenPolicies: []string{"test"},
TokenPeriod: 3 * time.Second,
TokenTTL: 1 * time.Second,
TokenMaxTTL: 5 * time.Second,
TokenNumUses: 12,
TokenBoundCIDRs: nil,
},
Policies: []string{"test"},
Period: 3 * time.Second,
ServiceAccountNames: []string{"name"},
ServiceAccountNamespaces: []string{"namespace"},
TTL: 1 * time.Second,
MaxTTL: 5 * time.Second,
NumUses: 12,
BoundCIDRs: nil,
AliasNameSource: aliasNameSourceDefault,
}

entry, err := logical.StorageEntryJSON("role/"+role, validRoleStorageEntry)
if err != nil {
t.Fatal(err)
}
if err := storage.Put(context.Background(), entry); err != nil {
t.Fatal(err)
}

loginData := map[string]interface{}{
"role": role,
}
loginReq := &logical.Request{
Operation: logical.ResolveRoleOperation,
Path: "login",
Storage: storage,
Data: loginData,
Connection: &logical.Connection{
RemoteAddr: "127.0.0.1",
},
}

resp, err := b.HandleRequest(context.Background(), loginReq)
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("err:%v resp:%#v", err, resp)
}

if resp.Data["role"] != role {
t.Fatalf("Role was not as expected. Expected %s, received %s", role, resp.Data["role"])
}
}

func TestResolveRole_RoleDoesNotExist(t *testing.T) {
b, storage := getBackend(t)
role := "testrole"

loginData := map[string]interface{}{
"role": role,
}
loginReq := &logical.Request{
Operation: logical.ResolveRoleOperation,
Path: "login",
Storage: storage,
Data: loginData,
Connection: &logical.Connection{
RemoteAddr: "127.0.0.1",
},
}

resp, err := b.HandleRequest(context.Background(), loginReq)
if resp == nil && !resp.IsError() {
t.Fatalf("Response was not an error: err:%v resp:%#v", err, resp)
}

errString, ok := resp.Data["error"].(string)
if !ok {
t.Fatal("Error not part of response.")
}

if !strings.Contains(errString, "invalid role name") {
t.Fatalf("Error was not due to invalid role name. Error: %s", errString)
}
}

0 comments on commit ae75c7e

Please sign in to comment.