Skip to content

Commit

Permalink
Allow Token Create Requests To Be Replicated (#18689)
Browse files Browse the repository at this point in the history
* Allow Token Create Requests To Be Replicated

* adding a test

* revert a test
  • Loading branch information
hghaf099 authored Jan 24, 2023
1 parent 4a6bfc9 commit 46b9921
Show file tree
Hide file tree
Showing 26 changed files with 435 additions and 422 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ SED?=$(shell command -v gsed || command -v sed)


GO_VERSION_MIN=$$(cat $(CURDIR)/.go-version)
PROTOC_VERSION_MIN=3.21.9
PROTOC_VERSION_MIN=3.21.12
GO_CMD?=go
CGO_ENABLED?=0
ifneq ($(FDB_ENABLED), )
Expand Down
2 changes: 1 addition & 1 deletion helper/forwarding/types.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion helper/identity/mfa/types.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion helper/identity/types.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion helper/storagepacker/types.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 1 addition & 8 deletions http/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -828,16 +828,9 @@ func handleRequestForwarding(core *vault.Core, handler http.Handler) http.Handle
return
}
path := ns.TrimmedPath(r.URL.Path[len("/v1/"):])
switch {
case !perfStandbyAlwaysForwardPaths.HasPath(path) && !alwaysRedirectPaths.HasPath(path):
if !perfStandbyAlwaysForwardPaths.HasPath(path) && !alwaysRedirectPaths.HasPath(path) {
handler.ServeHTTP(w, r)
return
case strings.HasPrefix(path, "auth/token/create/"):
isBatch, err := core.IsBatchTokenCreationRequest(r.Context(), path)
if err == nil && isBatch {
handler.ServeHTTP(w, r)
return
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion physical/raft/types.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion sdk/database/dbplugin/database.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion sdk/database/dbplugin/v5/proto/database.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion sdk/helper/pluginutil/multiplexing.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion sdk/logical/event.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion sdk/logical/identity.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion sdk/logical/plugin.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion sdk/logical/version.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

720 changes: 365 additions & 355 deletions sdk/plugin/pb/backend.pb.go

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions sdk/plugin/pb/backend.proto
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ message TokenEntry {
map<string, string> internal_meta = 19;
string inline_policy = 20;
bool no_identity_policies = 21;
string external_id = 22;
}

message LeaseOptions {
Expand Down
2 changes: 2 additions & 0 deletions sdk/plugin/pb/translation.go
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,7 @@ func LogicalTokenEntryToProtoTokenEntry(t *logical.TokenEntry) *TokenEntry {
NamespaceID: t.NamespaceID,
CubbyholeID: t.CubbyholeID,
Type: uint32(t.Type),
ExternalID: t.ExternalID,
}
}

Expand Down Expand Up @@ -660,6 +661,7 @@ func ProtoTokenEntryToLogicalTokenEntry(t *TokenEntry) (*logical.TokenEntry, err
NamespaceID: t.NamespaceID,
CubbyholeID: t.CubbyholeID,
Type: logical.TokenType(t.Type),
ExternalID: t.ExternalID,
}, nil
}

Expand Down
2 changes: 1 addition & 1 deletion vault/activity/activity_log.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion vault/hcp_link/proto/link_control/link_control.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion vault/hcp_link/proto/meta/meta.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion vault/hcp_link/proto/node_status/status.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion vault/request_forwarding_service.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 20 additions & 18 deletions vault/request_handling.go
Original file line number Diff line number Diff line change
Expand Up @@ -1201,26 +1201,28 @@ func (c *Core) handleRequest(ctx context.Context, req *logical.Request) (retResp
switch resp.Auth.TokenType {
case logical.TokenTypeBatch:
case logical.TokenTypeService:
registeredTokenEntry := &logical.TokenEntry{
TTL: auth.TTL,
Policies: auth.TokenPolicies,
Path: resp.Auth.CreationPath,
NamespaceID: ns.ID,
}
if err := c.expiration.RegisterAuth(ctx, registeredTokenEntry, resp.Auth, c.DetermineRoleFromLoginRequest(req.MountPoint, req.Data, ctx)); err != nil {
// Best-effort clean up on error, so we log the cleanup error as
// a warning but still return as internal error.
if err := c.tokenStore.revokeOrphan(ctx, resp.Auth.ClientToken); err != nil {
c.logger.Warn("failed to clean up token lease during auth/token/ request", "request_path", req.Path, "error", err)
if !c.perfStandby {
registeredTokenEntry := &logical.TokenEntry{
TTL: auth.TTL,
Policies: auth.TokenPolicies,
Path: resp.Auth.CreationPath,
NamespaceID: ns.ID,
}
c.logger.Error("failed to register token lease during auth/token/ request", "request_path", req.Path, "error", err)
retErr = multierror.Append(retErr, ErrInternalError)
return nil, auth, retErr
}
if registeredTokenEntry.ExternalID != "" {
resp.Auth.ClientToken = registeredTokenEntry.ExternalID
if err := c.expiration.RegisterAuth(ctx, registeredTokenEntry, resp.Auth, c.DetermineRoleFromLoginRequest(req.MountPoint, req.Data, ctx)); err != nil {
// Best-effort clean up on error, so we log the cleanup error as
// a warning but still return as internal error.
if err := c.tokenStore.revokeOrphan(ctx, resp.Auth.ClientToken); err != nil {
c.logger.Warn("failed to clean up token lease during auth/token/ request", "request_path", req.Path, "error", err)
}
c.logger.Error("failed to register token lease during auth/token/ request", "request_path", req.Path, "error", err)
retErr = multierror.Append(retErr, ErrInternalError)
return nil, auth, retErr
}
if registeredTokenEntry.ExternalID != "" {
resp.Auth.ClientToken = registeredTokenEntry.ExternalID
}
leaseGenerated = true
}
leaseGenerated = true
}
}

Expand Down
5 changes: 5 additions & 0 deletions vault/request_handling_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package vault
import (
"context"
"sync"
"time"

"github.com/hashicorp/vault/helper/identity"
"github.com/hashicorp/vault/sdk/logical"
Expand Down Expand Up @@ -80,3 +81,7 @@ func possiblyForwardSaveCachedAuthResponse(ctx context.Context, c *Core, respAut

return nil
}

func forwardCreateTokenRegisterAuth(ctx context.Context, c *Core, te *logical.TokenEntry, roleName string, renewable bool, periodToUse, explicitMaxTTLToUse time.Duration) (*logical.TokenEntry, error) {
return nil, nil
}
44 changes: 22 additions & 22 deletions vault/token_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -2067,25 +2067,6 @@ func (ts *TokenStore) revokeTreeInternal(ctx context.Context, id string) error {
return nil
}

func (c *Core) IsBatchTokenCreationRequest(ctx context.Context, path string) (bool, error) {
c.stateLock.RLock()
defer c.stateLock.RUnlock()

if c.tokenStore == nil {
return false, fmt.Errorf("no token store")
}

name := strings.TrimPrefix(path, "auth/token/create/")
roleEntry, err := c.tokenStore.tokenStoreRole(ctx, name)
if err != nil {
return false, err
}
if roleEntry == nil {
return false, fmt.Errorf("unknown role")
}
return roleEntry.TokenType == logical.TokenTypeBatch, nil
}

// handleCreateAgainstRole handles the auth/token/create path for a role
func (ts *TokenStore) handleCreateAgainstRole(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
name := d.Get("role_name").(string)
Expand Down Expand Up @@ -3171,9 +3152,22 @@ func (ts *TokenStore) handleCreateCommon(ctx context.Context, req *logical.Reque
resp.AddWarning("Supplying a custom ID for the token uses the weaker SHA1 hashing instead of the more secure SHA2-256 HMAC for token obfuscation. SHA1 hashed tokens on the wire leads to less secure lookups.")
}

// Create the token
if err := ts.create(ctx, &te); err != nil {
return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest
// check if we are perfStandby, and if so forward the service token
// creation to the active node
var roleName string
if role != nil {
roleName = role.Name
}
if te.Type == logical.TokenTypeService && ts.core.perfStandby {
forwardedTokenEntry, err := forwardCreateTokenRegisterAuth(ctx, ts.core, &te, roleName, renewable, periodToUse, explicitMaxTTLToUse)
if err != nil {
return logical.ErrorResponse(err.Error()), ErrInternalError
}
te = *forwardedTokenEntry
} else {
if err := ts.create(ctx, &te); err != nil {
return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest
}
}

// Count the successful token creation.
Expand Down Expand Up @@ -3211,6 +3205,12 @@ func (ts *TokenStore) handleCreateCommon(ctx context.Context, req *logical.Reque
Orphan: te.Parent == "",
}

// We have registered the auth at this point if the token is of service
// type and core is perfStandby.
if te.Type == logical.TokenTypeService && ts.core.perfStandby && te.ExternalID != "" {
resp.Auth.ClientToken = te.ExternalID
}

for _, p := range te.Policies {
policy, err := ts.core.policyStore.GetPolicy(ctx, p, PolicyTypeToken)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion vault/tokens/token.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 46b9921

Please sign in to comment.