diff --git a/command/token_create.go b/command/token_create.go index e564a3375a8f..3192cd9f282a 100644 --- a/command/token_create.go +++ b/command/token_create.go @@ -183,7 +183,7 @@ func (c *TokenCreateCommand) Flags() *FlagSets { Default: "", Usage: "Name of the entity alias to associate with during token creation. " + "Only works in combination with -role argument and used entity alias " + - "must be listed in allowed entity aliases. If this has been specified, " + + "must be listed in allowed_entity_aliases. If this has been specified, " + "the entity will not be inherited from the parent.", }) diff --git a/vault/token_store.go b/vault/token_store.go index 8034820f9812..cfe0333343e1 100644 --- a/vault/token_store.go +++ b/vault/token_store.go @@ -400,7 +400,7 @@ func (ts *TokenStore) paths() []*framework.Path { "allowed_entity_aliases": &framework.FieldSchema{ Type: framework.TypeStringSlice, - Description: "String or JSON list of allowed entity aliases. If set, specifies the entity aliases which are allowed to be used during token generation.", + Description: "String or JSON list of allowed entity aliases. If set, specifies the entity aliases which are allowed to be used during token generation. This field supports globbing.", }, }, @@ -2219,41 +2219,15 @@ func (ts *TokenStore) handleCreateCommon(ctx context.Context, req *logical.Reque return logical.ErrorResponse("'entity_alias' is only allowed in combination with token role"), logical.ErrInvalidRequest } - // Check if provided entity alias name is in the allowed entity aliases list + // Check if there is a concrete match match := false - for _, allowedAlias := range role.AllowedEntityAliases { - // Check if there is a match - if strings.EqualFold(allowedAlias, data.EntityAlias) { - match = true - break - } - - // Only continue when this allowed alias is a glob pattern - if !strings.Contains(allowedAlias, "*") { - continue - } - - // Split by asterisk to get prefix and suffix - split := strings.Split(allowedAlias, "*") - - // Multiple asterisks are not allowed. Skip this invalid glob pattern. - if len(split) != 2 { - continue - } - - // Check if prefix matches - if !strings.HasPrefix(data.EntityAlias, split[0]) { - continue - } - - // Check if suffix matches - if !strings.HasSuffix(data.EntityAlias, split[1]) { - continue - } + if strutil.StrListContains(role.AllowedEntityAliases, data.EntityAlias) { + match = true + } - // Found a match + // Check if there is a matching globbing pattern + if !match && strutil.StrListContainsGlob(role.AllowedEntityAliases, data.EntityAlias) { match = true - break } // Throw an error if it does not match @@ -2277,10 +2251,10 @@ func (ts *TokenStore) handleCreateCommon(ctx context.Context, req *logical.Reque // Create or fetch entity from entity alias entity, err := ts.core.identityStore.CreateOrFetchEntity(ctx, alias) if err != nil { - return logical.ErrorResponse(err.Error()), nil + return nil, err } if entity == nil { - return logical.ErrorResponse("failed to create or fetch entity from given entity alias"), nil + return nil, errors.New("failed to create or fetch entity from given entity alias") } // Validate that the entity is not disabled diff --git a/vault/token_store_test.go b/vault/token_store_test.go index 11dbbfa75ba1..47ea4f3796ad 100644 --- a/vault/token_store_test.go +++ b/vault/token_store_test.go @@ -2768,46 +2768,6 @@ func TestTokenStore_HandleRequest_CreateToken_NonExistingEntityAlias(t *testing. } } -func TestTokenStore_HandleRequest_CreateToken_GlobPattern_MultipleAsterisk_EntityAlias(t *testing.T) { - core, _, root := TestCoreUnsealed(t) - ctx := namespace.RootContext(nil) - entityAliasGlobPattern := "*testentity*" - entityAliasName := "testentity12345" - testRoleName := "test" - - // Create token role - resp, err := core.HandleRequest(ctx, &logical.Request{ - Path: "auth/token/roles/" + testRoleName, - ClientToken: root, - Operation: logical.CreateOperation, - Data: map[string]interface{}{ - "period": "72h", - "path_suffix": "happening", - "bound_cidrs": []string{"0.0.0.0/0"}, - "allowed_entity_aliases": []string{"test1", "test2", entityAliasGlobPattern}, - }, - }) - if err != nil || (resp != nil && resp.IsError()) { - t.Fatalf("err: %v\nresp: %#v", err, resp) - } - - // Create token with non existing entity alias - resp, err = core.HandleRequest(ctx, &logical.Request{ - Path: "auth/token/create/" + testRoleName, - Operation: logical.UpdateOperation, - ClientToken: root, - Data: map[string]interface{}{ - "entity_alias": entityAliasName, - }, - }) - if err == nil { - t.Fatal("err is nil but should be 'invalid request'") - } - if !strings.Contains(err.Error(), "invalid request") { - t.Fatalf("err should contain 'invalid request' but is '%s'", err.Error()) - } -} - func TestTokenStore_HandleRequest_CreateToken_GlobPatternWildcardEntityAlias(t *testing.T) { core, _, root := TestCoreUnsealed(t) i := core.identityStore diff --git a/vendor/github.com/hashicorp/vault/api/auth_token.go b/vendor/github.com/hashicorp/vault/api/auth_token.go index 6807c89c3878..ed594eee8528 100644 --- a/vendor/github.com/hashicorp/vault/api/auth_token.go +++ b/vendor/github.com/hashicorp/vault/api/auth_token.go @@ -272,5 +272,4 @@ type TokenCreateRequest struct { NumUses int `json:"num_uses"` Renewable *bool `json:"renewable,omitempty"` Type string `json:"type"` - EntityAlias string `json:"entity_alias"` } diff --git a/website/source/api/auth/token/index.html.md b/website/source/api/auth/token/index.html.md index 05d18328a259..00b58500f4e0 100644 --- a/website/source/api/auth/token/index.html.md +++ b/website/source/api/auth/token/index.html.md @@ -102,6 +102,10 @@ during this call. - `period` `(string: "")` - If specified, the token will be periodic; it will have no maximum TTL (unless an "explicit-max-ttl" is also set) but every renewal will use the given period. Requires a root/sudo token to use. +- `entity_alias` `string: "")` - Name of the entity alias to associate with + during token creation. Only works in combination with `role_name` argument + and used entity alias must be listed in `allowed_entity_aliases`. If this has + been specified, the entity will not be inherited from the parent. ### Sample Payload @@ -682,6 +686,9 @@ tokens created against a role to be revoked using the be returned unless the client requests a `batch` type token at token creation time. If `default-batch`, `batch` tokens will be returned unless the client requests a `service` type token at token creation time. +- `allowed_entity_aliases` `(string: "", or list: [])` - String or JSON list + of allowed entity aliases. If set, specifies the entity aliases which are + allowed to be used during token generation. This field supports globbing. ### Sample Payload