From 217bd67174fd5dd441e988452791648872d60558 Mon Sep 17 00:00:00 2001 From: David Adams Date: Sun, 18 Nov 2018 07:29:51 -0600 Subject: [PATCH 1/2] Allow globbing dis/allowed_policies in token roles * Add strutil functions to support glob comparisons and removals * Add logic to token grants to parse allowed_policies and disallowed_policies as potential globs * Also, filter out globs when granting default policies to a token --- sdk/helper/strutil/strutil.go | 23 +++++++++ sdk/helper/strutil/strutil_test.go | 59 ++++++++++++++++++++++ vault/token_store.go | 12 +++-- vault/token_store_test.go | 79 +++++++++++++++++++++++++++++- 4 files changed, 167 insertions(+), 6 deletions(-) diff --git a/sdk/helper/strutil/strutil.go b/sdk/helper/strutil/strutil.go index 0069a1377b2bb..6aee0b7b64186 100644 --- a/sdk/helper/strutil/strutil.go +++ b/sdk/helper/strutil/strutil.go @@ -43,6 +43,17 @@ func StrListSubset(super, sub []string) bool { return true } +// StrListSubsetGlob checks if a given list is a subset of +// another set, allowing for globs. +func StrListSubsetGlob(super, sub []string) bool { + for _, item := range sub { + if !StrListContainsGlob(super, item) { + return false + } + } + return true +} + // ParseDedupAndSortStrings parses a comma separated list of strings // into a slice of strings. The return slice will be sorted and will // not contain duplicate or empty items. @@ -277,6 +288,18 @@ func RemoveEmpty(items []string) []string { return itemsSlice } +// RemoveGlobs removes any elements containing globs from a slice of strings. +func RemoveGlobs(items []string) []string { + ret := make([]string, 0, len(items)) + for _, item := range items { + // glob.GLOB is "*"; ignore items containing that + if !strings.Contains(item, glob.GLOB) { + ret = append(ret, item) + } + } + return ret +} + // EquivalentSlices checks whether the given string sets are equivalent, as in, // they contain the same values. func EquivalentSlices(a, b []string) bool { diff --git a/sdk/helper/strutil/strutil_test.go b/sdk/helper/strutil/strutil_test.go index 698d2e82677b5..5ad5dd30d7ff3 100644 --- a/sdk/helper/strutil/strutil_test.go +++ b/sdk/helper/strutil/strutil_test.go @@ -135,6 +135,43 @@ func TestStrutil_ListSubset(t *testing.T) { } } +func TestStrutil_ListSubsetGlob(t *testing.T) { + parent := []string{ + "dev", + "ops*", + "root/*", + "*-dev", + "_*_", + } + if StrListSubsetGlob(parent, []string{"tubez", "dev", "root/admin"}) { + t.Fatalf("Bad") + } + if StrListSubsetGlob(parent, []string{"devops", "ops-dev"}) { + t.Fatalf("Bad") + } + if StrListSubsetGlob(nil, parent) { + t.Fatalf("Bad") + } + if !StrListSubsetGlob(parent, []string{"root/test", "dev", "_test_"}) { + t.Fatalf("Bad") + } + if !StrListSubsetGlob(parent, []string{"ops_test", "ops", "devops-dev"}) { + t.Fatalf("Bad") + } + if !StrListSubsetGlob(parent, []string{"ops"}) { + t.Fatalf("Bad") + } + if !StrListSubsetGlob(parent, []string{"test-dev"}) { + t.Fatalf("Bad") + } + if !StrListSubsetGlob(parent, []string{"_test_"}) { + t.Fatalf("Bad") + } + if !StrListSubsetGlob(parent, nil) { + t.Fatalf("Bad") + } +} + func TestStrutil_ParseKeyValues(t *testing.T) { actual := make(map[string]string) expected := map[string]string{ @@ -467,6 +504,28 @@ func TestStrUtil_RemoveDuplicatesStable(t *testing.T) { } } +func TestStrUtil_RemoveGlobs(t *testing.T) { + type tCase struct { + input []string + expect []string + } + + tCases := []tCase{ + tCase{[]string{}, []string{}}, + tCase{[]string{"hello"}, []string{"hello"}}, + tCase{[]string{"h*i"}, []string{}}, + tCase{[]string{"one", "two*", "*three", "f*our", "five"}, []string{"one", "five"}}, + } + + for _, tc := range tCases { + actual := RemoveGlobs(tc.input) + + if !reflect.DeepEqual(actual, tc.expect) { + t.Fatalf("Bad testcase %#v, expected %v, got %v", tc, tc.expect, actual) + } + } +} + func TestStrUtil_ParseStringSlice(t *testing.T) { type tCase struct { input string diff --git a/vault/token_store.go b/vault/token_store.go index 2a34d3289b60e..a68c41b95d6ed 100644 --- a/vault/token_store.go +++ b/vault/token_store.go @@ -2366,7 +2366,7 @@ func (ts *TokenStore) handleCreateCommon(ctx context.Context, req *logical.Reque if len(finalPolicies) == 0 { finalPolicies = sanitizedRolePolicies } else { - if !strutil.StrListSubset(sanitizedRolePolicies, finalPolicies) { + if !strutil.StrListSubsetGlob(sanitizedRolePolicies, finalPolicies) { return logical.ErrorResponse(fmt.Sprintf("token policies (%q) must be subset of the role's allowed policies (%q)", finalPolicies, sanitizedRolePolicies)), logical.ErrInvalidRequest } } @@ -2383,7 +2383,7 @@ func (ts *TokenStore) handleCreateCommon(ctx context.Context, req *logical.Reque sanitizedRolePolicies = strutil.RemoveDuplicates(role.DisallowedPolicies, true) for _, finalPolicy := range finalPolicies { - if strutil.StrListContains(sanitizedRolePolicies, finalPolicy) { + if strutil.StrListContainsGlob(sanitizedRolePolicies, finalPolicy) { return logical.ErrorResponse(fmt.Sprintf("token policy %q is disallowed by this role", finalPolicy)), logical.ErrInvalidRequest } } @@ -2441,6 +2441,9 @@ func (ts *TokenStore) handleCreateCommon(ctx context.Context, req *logical.Reque } } + // Remove any glob strings from policy list + te.Policies = strutil.RemoveGlobs(te.Policies) + if strutil.StrListContains(te.Policies, "root") { // Prevent attempts to create a root token without an actual root token as parent. // This is to thwart privilege escalation by tokens having 'sudo' privileges. @@ -3324,9 +3327,10 @@ as revocation of tokens. The tokens are renewable if associated with a lease.` tokenAllowedPoliciesHelp = `If set, tokens can be created with any subset of the policies in this list, rather than the normal semantics of tokens being a subset of the calling token's policies. The parameter is a comma-delimited string of -policy names.` +policy names or globs.` tokenDisallowedPoliciesHelp = `If set, successful token creation via this role will require that -no policies in the given list are requested. The parameter is a comma-delimited string of policy names.` +no policies in the given list are requested. The parameter is a comma-delimited string of policy names +or globs.` tokenOrphanHelp = `If true, tokens created via this role will be orphan tokens (have no parent)` tokenPeriodHelp = `If set, tokens created via this role diff --git a/vault/token_store_test.go b/vault/token_store_test.go index d03975d30b5da..3ad0329c6d8cf 100644 --- a/vault/token_store_test.go +++ b/vault/token_store_test.go @@ -3310,7 +3310,7 @@ func TestTokenStore_RoleDisallowedPolicies(t *testing.T) { ts := core.tokenStore ps := core.policyStore - // Create 3 different policies + // Create 4 different policies policy, _ := ParseACLPolicy(namespace.RootNamespace, tokenCreationPolicy) policy.Name = "test1" if err := ps.SetPolicy(namespace.RootContext(nil), policy); err != nil { @@ -3329,6 +3329,12 @@ func TestTokenStore_RoleDisallowedPolicies(t *testing.T) { t.Fatal(err) } + policy, _ = ParseACLPolicy(namespace.RootNamespace, tokenCreationPolicy) + policy.Name = "test3b" + if err := ps.SetPolicy(namespace.RootContext(nil), policy); err != nil { + t.Fatal(err) + } + // Create roles with different disallowed_policies configuration req = logical.TestRequest(t, logical.UpdateOperation, "roles/test1") req.ClientToken = root @@ -3360,10 +3366,20 @@ func TestTokenStore_RoleDisallowedPolicies(t *testing.T) { t.Fatalf("err:%v resp:%v", err, resp) } + req = logical.TestRequest(t, logical.UpdateOperation, "roles/testnot23") + req.ClientToken = root + req.Data = map[string]interface{}{ + "disallowed_policies": "test2,test3*", + } + resp, err = ts.HandleRequest(namespace.RootContext(nil), req) + if err != nil || (resp != nil && resp.IsError()) { + t.Fatalf("err:%v resp:%v", err, resp) + } + // Create a token that has all the policies defined above req = logical.TestRequest(t, logical.UpdateOperation, "create") req.ClientToken = root - req.Data["policies"] = []string{"test1", "test2", "test3"} + req.Data["policies"] = []string{"test1", "test2", "test3", "test3b"} resp = testMakeTokenViaRequest(t, ts, req) if resp == nil || resp.Auth == nil { t.Fatal("got nil response") @@ -3394,6 +3410,13 @@ func TestTokenStore_RoleDisallowedPolicies(t *testing.T) { t.Fatalf("expected an error response, got %#v", resp) } + req = logical.TestRequest(t, logical.UpdateOperation, "create/testnot23") + req.ClientToken = parentToken + resp, err = ts.HandleRequest(namespace.RootContext(nil), req) + if err == nil || resp != nil && !resp.IsError() { + t.Fatalf("expected an error response, got %#v", resp) + } + // Disallowed should act as a blacklist so make sure we can still make // something with other policies in the request req = logical.TestRequest(t, logical.UpdateOperation, "create/test123") @@ -3401,6 +3424,30 @@ func TestTokenStore_RoleDisallowedPolicies(t *testing.T) { req.ClientToken = parentToken testMakeTokenViaRequest(t, ts, req) + // Check to be sure 'test3*' matches 'test3' + req = logical.TestRequest(t, logical.UpdateOperation, "create/testnot23") + req.Data["policies"] = []string{"test3"} + req.ClientToken = parentToken + resp, err = ts.HandleRequest(namespace.RootContext(nil), req) + if err == nil || resp != nil && !resp.IsError() { + t.Fatalf("expected an error response, got %#v", resp) + } + + // Check to be sure 'test3*' matches 'test3b' + req = logical.TestRequest(t, logical.UpdateOperation, "create/testnot23") + req.Data["policies"] = []string{"test3b"} + req.ClientToken = parentToken + resp, err = ts.HandleRequest(namespace.RootContext(nil), req) + if err == nil || resp != nil && !resp.IsError() { + t.Fatalf("expected an error response, got %#v", resp) + } + + // Check that non-blacklisted policies still work + req = logical.TestRequest(t, logical.UpdateOperation, "create/testnot23") + req.Data["policies"] = []string{"test1"} + req.ClientToken = parentToken + testMakeTokenViaRequest(t, ts, req) + // Create a role to have 'default' policy disallowed req = logical.TestRequest(t, logical.UpdateOperation, "roles/default") req.ClientToken = root @@ -3453,6 +3500,34 @@ func TestTokenStore_RoleAllowedPolicies(t *testing.T) { t.Fatalf("bad: %#v", resp) } + // allowed_policies should also support globs + req = logical.TestRequest(t, logical.UpdateOperation, "roles/test") + req.ClientToken = root + req.Data = map[string]interface{}{ + "allowed_policies": "test*", + } + + resp, err = ts.HandleRequest(namespace.RootContext(nil), req) + if err != nil || (resp != nil && resp.IsError()) { + t.Fatalf("err: %v\nresp: %#v", err, resp) + } + if resp != nil { + t.Fatalf("expected a nil response") + } + + req.Path = "create/test" + req.Data["policies"] = []string{"footest"} + resp, err = ts.HandleRequest(namespace.RootContext(nil), req) + if err == nil { + t.Fatalf("expected error") + } + + req.Data["policies"] = []string{"testfoo", "test2"} + resp = testMakeTokenViaRequest(t, ts, req) + if resp.Auth.ClientToken == "" { + t.Fatalf("bad: %#v", resp) + } + // When allowed_policies is blank, should fall back to a subset of the parent policies req = logical.TestRequest(t, logical.UpdateOperation, "roles/test") req.ClientToken = root From d6fea845bfb6b5bbde788749656b2a3da25c6d57 Mon Sep 17 00:00:00 2001 From: Tiernan Messmer Date: Thu, 8 Aug 2019 18:03:48 +1000 Subject: [PATCH 2/2] Add allow_glob_policies flag to token role configuration. This controls the globbing behaviour of the allowed_policies and disallowed_policies fields. --- vault/token_store.go | 34 ++++++++++++--- vault/token_store_test.go | 89 +++++++++++++++++++++++++++++++++++---- 2 files changed, 108 insertions(+), 15 deletions(-) diff --git a/vault/token_store.go b/vault/token_store.go index a68c41b95d6ed..748a755121f89 100644 --- a/vault/token_store.go +++ b/vault/token_store.go @@ -362,6 +362,11 @@ func (ts *TokenStore) paths() []*framework.Path { Description: tokenDisallowedPoliciesHelp, }, + "allow_glob_policies": &framework.FieldSchema{ + Type: framework.TypeBool, + Description: tokenAllowGlobPoliciesHelp, + }, + "orphan": &framework.FieldSchema{ Type: framework.TypeBool, Description: tokenOrphanHelp, @@ -594,6 +599,9 @@ type tsRoleEntry struct { // List of policies to be not allowed during token creation using this role DisallowedPolicies []string `json:"disallowed_policies" mapstructure:"disallowed_policies" structs:"disallowed_policies"` + // If true, policies specified in allowed_policies and disallowed_policies will be matched as a glob + AllowGlobPolicies bool `json:"allow_glob_policies" mapstructure:"allow_glob_policies" structs:"allow_glob_policies"` + // If true, tokens created using this role will be orphans Orphan bool `json:"orphan" mapstructure:"orphan" structs:"orphan"` @@ -2366,7 +2374,8 @@ func (ts *TokenStore) handleCreateCommon(ctx context.Context, req *logical.Reque if len(finalPolicies) == 0 { finalPolicies = sanitizedRolePolicies } else { - if !strutil.StrListSubsetGlob(sanitizedRolePolicies, finalPolicies) { + if !(!role.AllowGlobPolicies && strutil.StrListSubset(sanitizedRolePolicies, finalPolicies)) && + !(role.AllowGlobPolicies && strutil.StrListSubsetGlob(sanitizedRolePolicies, finalPolicies)) { return logical.ErrorResponse(fmt.Sprintf("token policies (%q) must be subset of the role's allowed policies (%q)", finalPolicies, sanitizedRolePolicies)), logical.ErrInvalidRequest } } @@ -2383,7 +2392,8 @@ func (ts *TokenStore) handleCreateCommon(ctx context.Context, req *logical.Reque sanitizedRolePolicies = strutil.RemoveDuplicates(role.DisallowedPolicies, true) for _, finalPolicy := range finalPolicies { - if strutil.StrListContainsGlob(sanitizedRolePolicies, finalPolicy) { + if (!role.AllowGlobPolicies && strutil.StrListContains(sanitizedRolePolicies, finalPolicy)) || + (role.AllowGlobPolicies && strutil.StrListContainsGlob(sanitizedRolePolicies, finalPolicy)) { return logical.ErrorResponse(fmt.Sprintf("token policy %q is disallowed by this role", finalPolicy)), logical.ErrInvalidRequest } } @@ -2441,8 +2451,10 @@ func (ts *TokenStore) handleCreateCommon(ctx context.Context, req *logical.Reque } } - // Remove any glob strings from policy list - te.Policies = strutil.RemoveGlobs(te.Policies) + if role != nil && role.AllowGlobPolicies { + // Remove any glob strings from policy list + te.Policies = strutil.RemoveGlobs(te.Policies) + } if strutil.StrListContains(te.Policies, "root") { // Prevent attempts to create a root token without an actual root token as parent. @@ -3033,6 +3045,7 @@ func (ts *TokenStore) tokenStoreRoleRead(ctx context.Context, req *logical.Reque "token_explicit_max_ttl": int64(role.TokenExplicitMaxTTL.Seconds()), "disallowed_policies": role.DisallowedPolicies, "allowed_policies": role.AllowedPolicies, + "allow_glob_policies": role.AllowGlobPolicies, "name": role.Name, "orphan": role.Orphan, "path_suffix": role.PathSuffix, @@ -3136,6 +3149,13 @@ func (ts *TokenStore) tokenStoreRoleCreateUpdate(ctx context.Context, req *logic } else if req.Operation == logical.CreateOperation { entry.DisallowedPolicies = strutil.RemoveDuplicates(data.Get("disallowed_policies").([]string), true) } + + allowGlobPoliciesRaw, ok := data.GetOk("allow_glob_policies") + if ok { + entry.AllowGlobPolicies = allowGlobPoliciesRaw.(bool) + } else if req.Operation == logical.CreateOperation { + entry.AllowGlobPolicies = data.Get("allow_glob_policies").(bool) + } } // We handle token type a bit differently than tokenutil does so we need to @@ -3327,10 +3347,12 @@ as revocation of tokens. The tokens are renewable if associated with a lease.` tokenAllowedPoliciesHelp = `If set, tokens can be created with any subset of the policies in this list, rather than the normal semantics of tokens being a subset of the calling token's policies. The parameter is a comma-delimited string of -policy names or globs.` +policy names or globs when allow_glob_policies is true.` tokenDisallowedPoliciesHelp = `If set, successful token creation via this role will require that no policies in the given list are requested. The parameter is a comma-delimited string of policy names -or globs.` +or globs when allow_glob_policies is true.` + tokenAllowGlobPoliciesHelp = `If true, policies specified in allowed_policies and disallowed_policies +will be matched as a glob.` tokenOrphanHelp = `If true, tokens created via this role will be orphan tokens (have no parent)` tokenPeriodHelp = `If set, tokens created via this role diff --git a/vault/token_store_test.go b/vault/token_store_test.go index 3ad0329c6d8cf..a011e2aa8a361 100644 --- a/vault/token_store_test.go +++ b/vault/token_store_test.go @@ -3013,13 +3013,14 @@ func TestTokenStore_RoleCRUD(t *testing.T) { // First test creation req.Operation = logical.CreateOperation req.Data = map[string]interface{}{ - "orphan": true, - "period": "72h", - "allowed_policies": "test1,test2", - "path_suffix": "happenin", - "bound_cidrs": []string{"0.0.0.0/0"}, - "explicit_max_ttl": "2h", - "token_num_uses": 123, + "orphan": true, + "period": "72h", + "allowed_policies": "test1,test2", + "allow_glob_policies": true, + "path_suffix": "happenin", + "bound_cidrs": []string{"0.0.0.0/0"}, + "explicit_max_ttl": "2h", + "token_num_uses": 123, } resp, err = core.HandleRequest(namespace.RootContext(nil), req) @@ -3050,6 +3051,7 @@ func TestTokenStore_RoleCRUD(t *testing.T) { "period": int64(259200), "allowed_policies": []string{"test1", "test2"}, "disallowed_policies": []string{}, + "allow_glob_policies": true, "path_suffix": "happenin", "explicit_max_ttl": int64(7200), "token_explicit_max_ttl": int64(7200), @@ -3111,6 +3113,7 @@ func TestTokenStore_RoleCRUD(t *testing.T) { "token_period": int64(284400), "allowed_policies": []string{"test3"}, "disallowed_policies": []string{}, + "allow_glob_policies": true, "path_suffix": "happenin", "token_explicit_max_ttl": int64(288000), "explicit_max_ttl": int64(288000), @@ -3161,6 +3164,7 @@ func TestTokenStore_RoleCRUD(t *testing.T) { "token_explicit_max_ttl": int64(5), "allowed_policies": []string{"test3"}, "disallowed_policies": []string{}, + "allow_glob_policies": true, "path_suffix": "happenin", "period": int64(0), "token_period": int64(0), @@ -3211,6 +3215,7 @@ func TestTokenStore_RoleCRUD(t *testing.T) { "explicit_max_ttl": int64(5), "allowed_policies": []string{"test3"}, "disallowed_policies": []string{}, + "allow_glob_policies": true, "path_suffix": "", "period": int64(0), "token_period": int64(0), @@ -3369,6 +3374,7 @@ func TestTokenStore_RoleDisallowedPolicies(t *testing.T) { req = logical.TestRequest(t, logical.UpdateOperation, "roles/testnot23") req.ClientToken = root req.Data = map[string]interface{}{ + "allow_glob_policies": true, "disallowed_policies": "test2,test3*", } resp, err = ts.HandleRequest(namespace.RootContext(nil), req) @@ -3376,6 +3382,17 @@ func TestTokenStore_RoleDisallowedPolicies(t *testing.T) { t.Fatalf("err:%v resp:%v", err, resp) } + // glob policy without allow_glob_policies enabled + req = logical.TestRequest(t, logical.UpdateOperation, "roles/testglobdisabled") + req.ClientToken = root + req.Data = map[string]interface{}{ + "disallowed_policies": "test*", + } + resp, err = ts.HandleRequest(namespace.RootContext(nil), req) + if err != nil || (resp != nil && resp.IsError()) { + t.Fatalf("err:%v resp:%v", err, resp) + } + // Create a token that has all the policies defined above req = logical.TestRequest(t, logical.UpdateOperation, "create") req.ClientToken = root @@ -3442,6 +3459,21 @@ func TestTokenStore_RoleDisallowedPolicies(t *testing.T) { t.Fatalf("expected an error response, got %#v", resp) } + // Check to be sure 'test*' without globbing matches 'test*' + req = logical.TestRequest(t, logical.UpdateOperation, "create/testglobdisabled") + req.Data["policies"] = []string{"test*"} + req.ClientToken = parentToken + resp, err = ts.HandleRequest(namespace.RootContext(nil), req) + if err == nil || resp != nil && !resp.IsError() { + t.Fatalf("expected an error response, got %#v", resp) + } + + // Check to be sure 'test*' without globbing doesn't match 'test1' or 'test' + req = logical.TestRequest(t, logical.UpdateOperation, "create/testglobdisabled") + req.Data["policies"] = []string{"test1", "test"} + req.ClientToken = parentToken + testMakeTokenViaRequest(t, ts, req) + // Check that non-blacklisted policies still work req = logical.TestRequest(t, logical.UpdateOperation, "create/testnot23") req.Data["policies"] = []string{"test1"} @@ -3500,11 +3532,12 @@ func TestTokenStore_RoleAllowedPolicies(t *testing.T) { t.Fatalf("bad: %#v", resp) } - // allowed_policies should also support globs + // test glob matching when allow_glob_policies is true req = logical.TestRequest(t, logical.UpdateOperation, "roles/test") req.ClientToken = root req.Data = map[string]interface{}{ - "allowed_policies": "test*", + "allow_glob_policies": true, + "allowed_policies": "test*", } resp, err = ts.HandleRequest(namespace.RootContext(nil), req) @@ -3528,6 +3561,40 @@ func TestTokenStore_RoleAllowedPolicies(t *testing.T) { t.Fatalf("bad: %#v", resp) } + // test not glob matching when allow_glob_policies is false + req = logical.TestRequest(t, logical.UpdateOperation, "roles/testnoglob") + req.ClientToken = root + req.Data = map[string]interface{}{ + "allowed_policies": "test*", + } + + resp, err = ts.HandleRequest(namespace.RootContext(nil), req) + if err != nil || (resp != nil && resp.IsError()) { + t.Fatalf("err: %v\nresp: %#v", err, resp) + } + if resp != nil { + t.Fatalf("expected a nil response") + } + + req.Path = "create/testnoglob" + req.Data["policies"] = []string{"test"} + resp, err = ts.HandleRequest(namespace.RootContext(nil), req) + if err == nil { + t.Fatalf("expected error") + } + + req.Data["policies"] = []string{"testfoo"} + resp, err = ts.HandleRequest(namespace.RootContext(nil), req) + if err == nil { + t.Fatalf("expected error") + } + + req.Data["policies"] = []string{"test*"} + resp = testMakeTokenViaRequest(t, ts, req) + if resp.Auth.ClientToken == "" { + t.Fatalf("bad: %#v", resp) + } + // When allowed_policies is blank, should fall back to a subset of the parent policies req = logical.TestRequest(t, logical.UpdateOperation, "roles/test") req.ClientToken = root @@ -4096,6 +4163,7 @@ func TestTokenStore_RoleTokenFields(t *testing.T) { "token_period": int64(1), "allowed_policies": []string(nil), "disallowed_policies": []string(nil), + "allow_glob_policies": false, "path_suffix": "", "token_explicit_max_ttl": int64(3600), "explicit_max_ttl": int64(3600), @@ -4149,6 +4217,7 @@ func TestTokenStore_RoleTokenFields(t *testing.T) { "token_period": int64(5), "allowed_policies": []string(nil), "disallowed_policies": []string(nil), + "allow_glob_policies": false, "path_suffix": "", "token_explicit_max_ttl": int64(7200), "explicit_max_ttl": int64(7200), @@ -4201,6 +4270,7 @@ func TestTokenStore_RoleTokenFields(t *testing.T) { "token_period": int64(7), "allowed_policies": []string(nil), "disallowed_policies": []string(nil), + "allow_glob_policies": false, "path_suffix": "", "token_explicit_max_ttl": int64(5200), "explicit_max_ttl": int64(0), @@ -4255,6 +4325,7 @@ func TestTokenStore_RoleTokenFields(t *testing.T) { "token_period": int64(5), "allowed_policies": []string(nil), "disallowed_policies": []string(nil), + "allow_glob_policies": false, "path_suffix": "", "token_explicit_max_ttl": int64(7200), "explicit_max_ttl": int64(0),