Fix identity token caching (#8412)

The namespace-partitioned cache flushing was not being used correctly,
which could leave standby nodes with stale information.

Fixes #8284
This commit is contained in:
Jim Kalafut 2020-02-26 15:56:19 -05:00 committed by GitHub
parent 4b2bbe3f73
commit 90e8d9267d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 16 additions and 7 deletions

View File

@ -315,7 +315,15 @@ func (i *IdentityStore) Invalidate(ctx context.Context, key string) {
return
case strings.HasPrefix(key, oidcTokensPrefix):
if err := i.oidcCache.Flush(noNamespace); err != nil {
ns, err := namespace.FromContext(ctx)
if err != nil {
i.logger.Error("error retrieving namespace", "error", err)
return
}
// Wipe the cache for the requested namespace. This will also clear
// the shared namespace as well.
if err := i.oidcCache.Flush(ns); err != nil {
i.logger.Error("error flushing oidc cache", "error", err)
}
}

View File

@ -1564,8 +1564,6 @@ func (i *IdentityStore) oidcPeriodicFunc(ctx context.Context) {
var nextRun time.Time
now := time.Now()
nsPaths := i.listNamespacePaths()
v, ok, err := i.oidcCache.Get(noNamespace, "nextRun")
if err != nil {
i.Logger().Error("error reading oidc cache", "err", err)
@ -1585,7 +1583,9 @@ func (i *IdentityStore) oidcPeriodicFunc(ctx context.Context) {
// based on key rotation times.
nextRun = now.Add(24 * time.Hour)
for _, nsPath := range nsPaths {
for _, ns := range i.listNamespaces() {
nsPath := ns.Path
s := i.core.router.MatchingStorageByAPIPath(ctx, nsPath+"identity/oidc")
if s == nil {
@ -1602,7 +1602,7 @@ func (i *IdentityStore) oidcPeriodicFunc(ctx context.Context) {
i.Logger().Warn("error expiring OIDC public keys", "err", err)
}
if err := i.oidcCache.Flush(noNamespace); err != nil {
if err := i.oidcCache.Flush(ns); err != nil {
i.Logger().Error("error flushing oidc cache", "err", err)
}
@ -1653,6 +1653,7 @@ func (c *oidcCache) Flush(ns *namespace.Namespace) error {
return errNilNamespace
}
// Remove all items from the provided namespace as well as the shared, "no namespace" section.
for itemKey := range c.c.Items() {
if isTargetNamespacedKey(itemKey, []string{noNamespace.ID, ns.ID}) {
c.c.Delete(itemKey)

View File

@ -6,6 +6,6 @@ import (
"github.com/hashicorp/vault/helper/namespace"
)
func (i *IdentityStore) listNamespacePaths() []string {
return []string{namespace.RootNamespace.Path}
func (i *IdentityStore) listNamespaces() []*namespace.Namespace {
return []*namespace.Namespace{namespace.RootNamespace}
}