Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Glob/Wildcard support for roles #58

Merged
merged 1 commit into from
Jun 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions path_login.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,14 +193,14 @@ func (b *kubeAuthBackend) parseAndValidateJWT(jwtStr string, role *roleStorageEn

// verify the namespace is allowed
if len(role.ServiceAccountNamespaces) > 1 || role.ServiceAccountNamespaces[0] != "*" {
if !strutil.StrListContains(role.ServiceAccountNamespaces, sa.namespace()) {
if !strutil.StrListContainsGlob(role.ServiceAccountNamespaces, sa.namespace()) {
return errors.New("namespace not authorized")
}
}

// verify the service account name is allowed
if len(role.ServiceAccountNames) > 1 || role.ServiceAccountNames[0] != "*" {
if !strutil.StrListContains(role.ServiceAccountNames, sa.name()) {
if !strutil.StrListContainsGlob(role.ServiceAccountNames, sa.name()) {
return errors.New("service account name not authorized")
}
}
Expand Down
59 changes: 51 additions & 8 deletions path_login_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ var (
testUID = "d77f89bc-9055-11e7-a068-0800276d99bf"
testMockFactory = mockTokenReviewFactory(testName, testNamespace, testUID)

testGlobbedNamespace = "def*"
testGlobbedName = "vault-*"

// Projected ServiceAccount tokens have name "default", and require a
// different mock token reviewer
testProjectedName = "default"
Expand All @@ -28,7 +31,7 @@ var (
testNoPEMs = []string{testECCert, testRSACert}
)

func setupBackend(t *testing.T, pems []string) (logical.Backend, logical.Storage) {
func setupBackend(t *testing.T, pems []string, saName string, saNamespace string) (logical.Backend, logical.Storage) {
b, storage := getBackend(t)

// pems := []string{testECCert, testRSACert, testMinikubePubKey}
Expand Down Expand Up @@ -57,8 +60,8 @@ func setupBackend(t *testing.T, pems []string) (logical.Backend, logical.Storage
}

data = map[string]interface{}{
"bound_service_account_names": testName,
"bound_service_account_namespaces": testNamespace,
"bound_service_account_names": saName,
"bound_service_account_namespaces": saNamespace,
"policies": "test",
"period": "3s",
"ttl": "1s",
Expand All @@ -83,7 +86,7 @@ func setupBackend(t *testing.T, pems []string) (logical.Backend, logical.Storage
}

func TestLogin(t *testing.T) {
b, storage := setupBackend(t, testDefaultPEMs)
b, storage := setupBackend(t, testDefaultPEMs, testName, testNamespace)

// Test bad inputs
data := map[string]interface{}{
Expand Down Expand Up @@ -203,10 +206,50 @@ func TestLogin(t *testing.T) {
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("err:%s resp:%#v\n", err, resp)
}

// test successful login for globbed name
b, storage = setupBackend(t, testDefaultPEMs, testGlobbedName, testNamespace)

data = map[string]interface{}{
"role": "plugin-test",
"jwt": jwtData,
}

req = &logical.Request{
Operation: logical.UpdateOperation,
Path: "login",
Storage: storage,
Data: data,
}

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

// test successful login for globbed namespace
b, storage = setupBackend(t, testDefaultPEMs, testName, testGlobbedNamespace)

data = map[string]interface{}{
"role": "plugin-test",
"jwt": jwtData,
}

req = &logical.Request{
Operation: logical.UpdateOperation,
Path: "login",
Storage: storage,
Data: data,
}

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

func TestLogin_ECDSA_PEM(t *testing.T) {
b, storage := setupBackend(t, testNoPEMs)
b, storage := setupBackend(t, testNoPEMs, testName, testNamespace)

// test no certificate
data := map[string]interface{}{
Expand Down Expand Up @@ -247,7 +290,7 @@ func TestLogin_ECDSA_PEM(t *testing.T) {
}

func TestLogin_NoPEMs(t *testing.T) {
b, storage := setupBackend(t, testNoPEMs)
b, storage := setupBackend(t, testNoPEMs, testName, testNamespace)

// test bad jwt service account
data := map[string]interface{}{
Expand Down Expand Up @@ -289,7 +332,7 @@ func TestLogin_NoPEMs(t *testing.T) {
}

func TestAliasLookAhead(t *testing.T) {
b, storage := setupBackend(t, testDefaultPEMs)
b, storage := setupBackend(t, testDefaultPEMs, testName, testNamespace)

// Test bad inputs
data := map[string]interface{}{
Expand Down Expand Up @@ -328,7 +371,7 @@ Pk9Yf9rIf374m5XP1U8q79dBhLSIuaojsvOT39UUcPJROSD1FqYLued0rXiooIii
-----END PUBLIC KEY-----`

func TestLoginProjectedToken(t *testing.T) {
b, storage := setupBackend(t, append(testDefaultPEMs, testMinikubePubKey))
b, storage := setupBackend(t, append(testDefaultPEMs, testMinikubePubKey), testName, testNamespace)

// update backend to accept "default" bound account name
data := map[string]interface{}{
Expand Down