From b9c892f8aa37c130dbb46c39972dccbaed42ba1b Mon Sep 17 00:00:00 2001 From: Violet Hynes Date: Wed, 10 Jul 2024 09:38:51 -0400 Subject: [PATCH] VAULT-28656 CE changes for Proxy bug (#27730) * VAULT-28656 CE changes for Proxy bug * VAULT-28656 changelog * VAULT-28656 rename changelog --- changelog/27730.txt | 3 +++ command/agentproxyshared/cache/lease_cache.go | 5 +++-- .../cache/static_secret_cache_updater.go | 11 ++++++++++- .../cache/static_secret_cache_updater_test.go | 2 +- 4 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 changelog/27730.txt diff --git a/changelog/27730.txt b/changelog/27730.txt new file mode 100644 index 0000000000..d265306293 --- /dev/null +++ b/changelog/27730.txt @@ -0,0 +1,3 @@ +```release-note:bug +proxy/cache (enterprise): Fixed an issue where cached static secrets could fail to update if the secrets belonged to a non-root namespace. +``` diff --git a/command/agentproxyshared/cache/lease_cache.go b/command/agentproxyshared/cache/lease_cache.go index 6e8b564a62..a9ea65806d 100644 --- a/command/agentproxyshared/cache/lease_cache.go +++ b/command/agentproxyshared/cache/lease_cache.go @@ -411,7 +411,7 @@ func (c *LeaseCache) Send(ctx context.Context, req *SendRequest) (*SendResponse, return nil, err } if cachedResp != nil { - c.logger.Debug("returning cached static secret response", "id", staticSecretCacheId, "path", req.Request.URL.Path) + c.logger.Debug("returning cached static secret response", "id", staticSecretCacheId, "path", getStaticSecretPathFromRequest(req)) return cachedResp, nil } } @@ -482,6 +482,7 @@ func (c *LeaseCache) Send(ctx context.Context, req *SendRequest) (*SendResponse, // included in the request path. index.RequestPath = getStaticSecretPathFromRequest(req) + c.logger.Trace("attempting to cache static secret with following request path", "request path", index.RequestPath) err := c.cacheStaticSecret(ctx, req, resp, index) if err != nil { return nil, err @@ -665,7 +666,7 @@ func (c *LeaseCache) cacheStaticSecret(ctx context.Context, req *SendRequest, re func (c *LeaseCache) storeStaticSecretIndex(ctx context.Context, req *SendRequest, index *cachememdb.Index) error { // Store the index in the cache - c.logger.Debug("storing static secret response into the cache", "method", req.Request.Method, "path", req.Request.URL.Path, "id", index.ID) + c.logger.Debug("storing static secret response into the cache", "method", req.Request.Method, "path", index.RequestPath, "id", index.ID) err := c.Set(ctx, index) if err != nil { c.logger.Error("failed to cache the proxied response", "error", err) diff --git a/command/agentproxyshared/cache/static_secret_cache_updater.go b/command/agentproxyshared/cache/static_secret_cache_updater.go index 9499569cff..ea21f43b7d 100644 --- a/command/agentproxyshared/cache/static_secret_cache_updater.go +++ b/command/agentproxyshared/cache/static_secret_cache_updater.go @@ -163,6 +163,10 @@ func (updater *StaticSecretCacheUpdater) streamStaticSecretEvents(ctx context.Co if !ok { return fmt.Errorf("unexpected event format when decoding 'path' element, message: %s\nerror: %w", string(message), err) } + namespace, ok := data["namespace"].(string) + if ok { + path = namespace + path + } err := updater.updateStaticSecret(ctx, path) if err != nil { // While we are kind of 'missing' an event this way, re-calling this function will @@ -218,6 +222,10 @@ func (updater *StaticSecretCacheUpdater) updateStaticSecret(ctx context.Context, return err } + // Clear the client's header namespace since we'll be including the + // namespace as part of the path. + client.ClearNamespace() + indexId := hashStaticSecretIndex(path) updater.logger.Debug("received update static secret request", "path", path, "indexId", indexId) @@ -248,7 +256,7 @@ func (updater *StaticSecretCacheUpdater) updateStaticSecret(ctx context.Context, request.Headers.Set(api.AuthHeaderName, token) resp, err = client.RawRequestWithContext(ctx, request) if err != nil { - updater.logger.Trace("received error when trying to update cache", "path", path, "err", err, "token", token) + updater.logger.Trace("received error when trying to update cache", "path", path, "err", err, "token", token, "namespace", index.Namespace) // We cannot access this secret with this token for whatever reason, // so token for removal. tokensToRemove = append(tokensToRemove, token) @@ -329,6 +337,7 @@ func (updater *StaticSecretCacheUpdater) openWebSocketConnection(ctx context.Con } query := webSocketURL.Query() query.Set("json", "true") + query.Set("namespaces", "*") webSocketURL.RawQuery = query.Encode() updater.client.AddHeader(api.AuthHeaderName, updater.client.Token()) diff --git a/command/agentproxyshared/cache/static_secret_cache_updater_test.go b/command/agentproxyshared/cache/static_secret_cache_updater_test.go index 51c53b2fc3..91158d954c 100644 --- a/command/agentproxyshared/cache/static_secret_cache_updater_test.go +++ b/command/agentproxyshared/cache/static_secret_cache_updater_test.go @@ -407,7 +407,7 @@ func TestOpenWebSocketConnectionReceivesEventsKVV1(t *testing.T) { } } -// TestOpenWebSocketConnectionReceivesEvents tests that the openWebSocketConnection function +// TestOpenWebSocketConnectionReceivesEventsKVV2 tests that the openWebSocketConnection function // works as expected with KVV2, and then the connection can be used to receive an event. // This acts as more of an event system sanity check than a test of the updater // logic. It's still important coverage, though.