cache

package
v1.16.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 5, 2026 License: Apache-2.0 Imports: 28 Imported by: 5

Documentation

Index

Constants

View Source
const (
	// DefaultSVIDCacheMaxSize is set when svidCacheMaxSize is not provided
	DefaultSVIDCacheMaxSize = 1000
	// SVIDSyncInterval is the interval at which SVIDs are synced with subscribers
	SVIDSyncInterval = 500 * time.Millisecond
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Bundle

type Bundle = spiffebundle.Bundle

type BundleCache

type BundleCache struct {
	// contains filtered or unexported fields
}

func NewBundleCache

func NewBundleCache(trustDomain spiffeid.TrustDomain, bundle *Bundle) *BundleCache

func (*BundleCache) Bundle

func (c *BundleCache) Bundle() *Bundle

func (*BundleCache) Bundles

func (c *BundleCache) Bundles() map[spiffeid.TrustDomain]*Bundle

func (*BundleCache) GetX509BundleForTrustDomain added in v1.15.2

func (c *BundleCache) GetX509BundleForTrustDomain(trustDomain spiffeid.TrustDomain) (*x509bundle.Bundle, error)

func (*BundleCache) SubscribeToBundleChanges

func (c *BundleCache) SubscribeToBundleChanges() *BundleStream

func (*BundleCache) Update

func (c *BundleCache) Update(bundles map[spiffeid.TrustDomain]*Bundle)

type BundleStream

type BundleStream struct {
	// contains filtered or unexported fields
}

Wraps an observer stream to provide a type safe interface

func NewBundleStream

func NewBundleStream(stream observer.Stream) *BundleStream

func (*BundleStream) Changes

func (b *BundleStream) Changes() chan struct{}

Changes returns the channel that is closed when a new value is available.

func (*BundleStream) Clone

func (b *BundleStream) Clone() *BundleStream

Clone creates a new independent stream from this one but sharing the same Property. Updates to the property will be reflected in both streams, but they may have different values depending on when they advance the stream with Next.

func (*BundleStream) HasNext

func (b *BundleStream) HasNext() bool

HasNext checks whether there is a new value available.

func (*BundleStream) Next

func (b *BundleStream) Next() map[spiffeid.TrustDomain]*Bundle

Next advances this stream to the next state. You should never call this unless Changes channel is closed.

func (*BundleStream) Value

func (b *BundleStream) Value() map[spiffeid.TrustDomain]*Bundle

Value returns the current value for this stream.

func (*BundleStream) WaitNext

func (b *BundleStream) WaitNext() map[spiffeid.TrustDomain]*Bundle

WaitNext waits for Changes to be closed, advances the stream and returns the current value.

type CachedSVID added in v1.16.0

type CachedSVID interface {
	ExpiresAt() time.Time

	// InvalidatedBy reports whether an SVID issued for the issued entry
	// must not be served to workloads matching only the updated entry.
	InvalidatedBy(issued, updated *common.RegistrationEntry) bool
}

CachedSVID is the constraint for any SVID type storable in the generic LRU cache.

type JWTSVIDCache

type JWTSVIDCache struct {
	// contains filtered or unexported fields
}

func NewJWTSVIDCache

func NewJWTSVIDCache(log logrus.FieldLogger, metrics telemetry.Metrics, svidCacheMaxSize int) *JWTSVIDCache

func (*JWTSVIDCache) CountJWTSVIDs added in v1.10.2

func (c *JWTSVIDCache) CountJWTSVIDs() int

func (*JWTSVIDCache) GetJWTSVID

func (c *JWTSVIDCache) GetJWTSVID(spiffeID spiffeid.ID, audience []string) (*client.JWTSVID, bool)

func (*JWTSVIDCache) SetJWTSVID

func (c *JWTSVIDCache) SetJWTSVID(spiffeID spiffeid.ID, audience []string, svid *client.JWTSVID)

func (*JWTSVIDCache) TaintJWTSVIDs added in v1.11.0

func (c *JWTSVIDCache) TaintJWTSVIDs(ctx context.Context, taintedJWTAuthorities map[string]struct{})

type LRUCache added in v1.4.4

type LRUCache[SVID CachedSVID, Update any] struct {
	// contains filtered or unexported fields
}

LRUCache caches registration entries, bundles, and SVIDs for the agent. It is parameterized by SVID (the SVID type) and Update (the update payload sent to subscribers).

It allows subscriptions by (workload) selector sets and notifies subscribers when:

1) a registration entry related to the selectors:

  • is modified
  • has a new SVID signed for it
  • federates with a federated bundle that is updated or removed

2) the trust bundle for the agent trust domain is updated

When notified, the subscriber is given a WorkloadUpdate containing related identities and trust bundles.

The cache does this efficiently by building an index for each unique selector it encounters. Each selector index tracks the subscribers (i.e. workloads) and registration entries that have that selector.

The LRU-like SVID cache has a size limit and expiry period.

  1. Size limit of SVID cache is a soft limit. If SVID has a subscriber present then that SVID is never removed from cache.
  2. Least recently used SVIDs are removed from cache only after the cache expiry period has passed. This is done to reduce the overall cache churn.
  3. Last access timestamp for SVID cache entry is updated when a new subscriber is created
  4. When a new subscriber is created and there is a cache miss then subscriber needs to wait for next SVID sync event to receive WorkloadUpdate with newly minted SVID

The advantage of above approach is that if agent has entry count less than cache size then all SVIDs are cached at all times. If agent has entry count greater than cache size then subscribers will continue to get SVID updates (potential delay for first WorkloadUpdate if cache miss) and least used SVIDs will be removed from cache which will save memory usage. This allows agent to support environments where the active simultaneous workload count is a small percentage of the large number of registrations assigned to the agent.

When registration entries are added/updated/removed, the set of relevant selectors are gathered and the indexes for those selectors are combed for all relevant subscribers.

For each relevant subscriber, the selector index for each selector of the subscriber is combed for registration whose selectors are a subset of the subscriber selector set. Identities for those entries are added to the workload update returned to the subscriber.

NOTE: The cache is intended to be able to handle thousands of workload subscriptions, which can involve thousands of certificates, keys, bundles, and registration entries, etc. The selector index itself is intended to be scalable, but the objects themselves can take a considerable amount of memory. For maximal safety, the objects should be cloned both coming in and leaving the cache. However, during global updates (e.g. trust bundle is updated for the agent trust domain) in particular, cloning all of the relevant objects for each subscriber causes HUGE amounts of memory pressure which adds non-trivial amounts of latency and causes a giant memory spike that could OOM the agent on smaller VMs. For this reason, the cache is presumed to own ALL data passing in and out of the cache. Producers and consumers MUST NOT mutate the data.

func NewLRUCache added in v1.4.4

func NewLRUCache[SVID CachedSVID, Update any](config LRUCacheConfig[SVID, Update]) *LRUCache[SVID, Update]

func (*LRUCache[SVID, Update]) CountRecords added in v1.7.2

func (c *LRUCache[SVID, Update]) CountRecords() int

func (*LRUCache[SVID, Update]) CountSVIDs added in v1.4.4

func (c *LRUCache[SVID, Update]) CountSVIDs() int

func (*LRUCache[SVID, Update]) Entries added in v1.4.4

func (c *LRUCache[SVID, Update]) Entries() []*common.RegistrationEntry

func (*LRUCache[SVID, Update]) FetchWorkloadUpdate added in v1.4.4

func (c *LRUCache[SVID, Update]) FetchWorkloadUpdate(selectors []*common.Selector) *Update

func (*LRUCache[SVID, Update]) GatherFederatedBundles added in v1.16.0

func (c *LRUCache[SVID, Update]) GatherFederatedBundles(entries []*common.RegistrationEntry) map[spiffeid.TrustDomain]*spiffebundle.Bundle

GatherFederatedBundles returns the federated trust bundles referenced by the FederatesWith declarations of the given entries. Callers must hold the read lock.

func (*LRUCache[SVID, Update]) GetStaleEntries added in v1.4.4

func (c *LRUCache[SVID, Update]) GetStaleEntries() []*StaleEntry

GetStaleEntries obtains a list of stale entries

func (*LRUCache[SVID, Update]) MatchingRegistrationEntries added in v1.4.4

func (c *LRUCache[SVID, Update]) MatchingRegistrationEntries(selectors []*common.Selector) []*common.RegistrationEntry

func (*LRUCache[SVID, Update]) NewSubscriber added in v1.4.4

func (c *LRUCache[SVID, Update]) NewSubscriber(selectors []*common.Selector) Subscriber[Update]

NewSubscriber creates a subscriber for given selector set. Separately call Notify for the first time after this method is invoked to receive latest updates.

func (*LRUCache[SVID, Update]) SubscribeToWorkloadUpdates added in v1.4.4

func (c *LRUCache[SVID, Update]) SubscribeToWorkloadUpdates(ctx context.Context, selectors Selectors) (Subscriber[Update], error)

func (*LRUCache[SVID, Update]) SyncSVIDsWithSubscribers added in v1.4.4

func (c *LRUCache[SVID, Update]) SyncSVIDsWithSubscribers()

SyncSVIDsWithSubscribers will sync svid cache: entries with active subscribers which are not cached will be put in staleEntries map records which are not cached for remainder of max cache size will also be put in staleEntries map

func (*LRUCache[SVID, Update]) UpdateEntries added in v1.4.4

func (c *LRUCache[SVID, Update]) UpdateEntries(update *UpdateEntries, checkSVID func(*common.RegistrationEntry, *common.RegistrationEntry, *SVID) bool)

UpdateEntries updates the cache with the provided registration entries and bundles and notifies impacted subscribers. The checkSVID callback, if provided, is used to determine if the SVID for the entry is stale, or otherwise in need of rotation. Entries marked stale through the checkSVID callback are returned from GetStaleEntries() until the SVID is updated through a call to UpdateSVIDs.

func (*LRUCache[SVID, Update]) UpdateSVIDs added in v1.4.4

func (c *LRUCache[SVID, Update]) UpdateSVIDs(svids map[string]*SVID)

UpdateSVIDs updates SVIDs in the cache for the given entries.

type LRUCacheConfig added in v1.16.0

type LRUCacheConfig[SVID CachedSVID, Update any] struct {
	Log              logrus.FieldLogger
	TrustDomain      spiffeid.TrustDomain
	Bundle           *Bundle
	Metrics          telemetry.Metrics
	SvidCacheMaxSize int
	Clk              clock.Clock

	// SVIDType identifies the type of SVID stored in the cache.
	SVIDType string

	// BuildUpdate constructs the typed update from matching records, SVIDs, and bundles.
	BuildUpdate func(cache *LRUCache[SVID, Update], set selectorSet) *Update

	// ShouldPrefetch determines whether a given entry should be prefetched.
	// If nil, all entries are eligible for prefetch.
	ShouldPrefetch func(*common.RegistrationEntry) bool
}

LRUCacheConfig holds configuration for creating an LRUCache instance.

type Selectors

type Selectors []*common.Selector

type StaleEntry added in v0.10.0

type StaleEntry struct {
	// Entry stale registration entry
	Entry *common.RegistrationEntry
	// SVIDs expiration time
	SVIDExpiresAt time.Time
}

StaleEntry holds stale entries with SVIDs expiration time

type Subscriber

type Subscriber[U any] interface {
	Updates() <-chan *U
	Finish()
}

Subscriber is the public interface for cache subscribers.

type UpdateEntries added in v0.10.0

type UpdateEntries struct {
	// Bundles is a set of ALL trust bundles available to the agent, keyed by trust domain
	Bundles map[spiffeid.TrustDomain]*spiffebundle.Bundle

	// RegistrationEntries is a set of all registration entries available to the
	// agent, keyed by registration entry id.
	RegistrationEntries map[string]*common.RegistrationEntry
}

UpdateEntries holds information for an entries update to the cache.

type WITIdentity added in v1.16.0

type WITIdentity struct {
	Entry      *common.RegistrationEntry
	Token      string
	PrivateKey crypto.Signer
}

WITIdentity holds the data for a single WIT-SVID workload identity.

func (WITIdentity) GetEntry added in v1.16.0

func (i WITIdentity) GetEntry() *common.RegistrationEntry

GetEntry returns the registration entry the identity was issued for.

type WITLRUCache added in v1.16.0

type WITLRUCache struct {
	*LRUCache[WITSVID, WITWorkloadUpdate]
}

WITLRUCache wraps LRUCache with WIT-SVID-specific operations.

func NewWITLRUCache added in v1.16.0

func NewWITLRUCache(config WITLRUCacheConfig) *WITLRUCache

func (*WITLRUCache) UpdateWITSVIDs added in v1.16.0

func (c *WITLRUCache) UpdateWITSVIDs(svids map[string]*WITSVID)

type WITLRUCacheConfig added in v1.16.0

type WITLRUCacheConfig struct {
	Log              logrus.FieldLogger
	TrustDomain      spiffeid.TrustDomain
	Bundle           *Bundle
	Metrics          telemetry.Metrics
	SvidCacheMaxSize int
	Clk              clock.Clock
}

type WITSVID added in v1.16.0

type WITSVID struct {
	Token      string
	PrivateKey crypto.Signer
	IssuedAt   time.Time
	ExpiresOn  time.Time
}

WITSVID holds onto the WIT-SVID token and private key.

func (WITSVID) ExpiresAt added in v1.16.0

func (s WITSVID) ExpiresAt() time.Time

func (WITSVID) InvalidatedBy added in v1.16.0

func (s WITSVID) InvalidatedBy(issued, updated *common.RegistrationEntry) bool

type WITWorkloadUpdate added in v1.16.0

type WITWorkloadUpdate struct {
	Identities       []WITIdentity
	Bundle           *spiffebundle.Bundle
	FederatedBundles map[spiffeid.TrustDomain]*spiffebundle.Bundle
}

WITWorkloadUpdate is used to convey WIT workload information to cache subscribers.

func (*WITWorkloadUpdate) HasIdentity added in v1.16.0

func (u *WITWorkloadUpdate) HasIdentity() bool

type X509Identity added in v1.16.0

type X509Identity struct {
	Entry      *common.RegistrationEntry
	SVID       []*x509.Certificate
	PrivateKey crypto.Signer
}

X509Identity holds the data for a single X509 workload identity.

func (X509Identity) GetEntry added in v1.16.0

func (i X509Identity) GetEntry() *common.RegistrationEntry

GetEntry returns the registration entry the identity was issued for.

type X509LRUCacheConfig added in v1.16.0

type X509LRUCacheConfig struct {
	Log              logrus.FieldLogger
	TrustDomain      spiffeid.TrustDomain
	Bundle           *Bundle
	Metrics          telemetry.Metrics
	SvidCacheMaxSize int
	Clk              clock.Clock

	// ShouldPrefetch determines whether a given entry should be prefetched.
	// If nil, entries are eligible for prefetch unless they disable it via
	// AdditionalAttributes.
	ShouldPrefetch func(*common.RegistrationEntry) bool
}

type X509SVID

type X509SVID struct {
	Chain      []*x509.Certificate
	PrivateKey crypto.Signer
}

X509SVID holds onto the SVID certificate chain and private key.

func (X509SVID) ExpiresAt added in v1.16.0

func (s X509SVID) ExpiresAt() time.Time

func (X509SVID) InvalidatedBy added in v1.16.0

func (s X509SVID) InvalidatedBy(issued, updated *common.RegistrationEntry) bool

type X509SVIDLRUCache added in v1.16.0

type X509SVIDLRUCache struct {
	*LRUCache[X509SVID, X509WorkloadUpdate]
	// contains filtered or unexported fields
}

X509SVIDLRUCache wraps LRUCache with X509-specific operations.

func NewX509LRUCache added in v1.16.0

func NewX509LRUCache(config X509LRUCacheConfig) *X509SVIDLRUCache

func (*X509SVIDLRUCache) Identities added in v1.16.0

func (c *X509SVIDLRUCache) Identities() []X509Identity

Identities is only used by manager tests.

func (*X509SVIDLRUCache) TaintX509SVIDs added in v1.16.0

func (c *X509SVIDLRUCache) TaintX509SVIDs(ctx context.Context, taintedX509Authorities []*x509.Certificate)

TaintX509SVIDs initiates the processing of all cached SVIDs, checking if they are tainted by any of the provided authorities.

func (*X509SVIDLRUCache) UpdateX509SVIDs added in v1.16.0

func (c *X509SVIDLRUCache) UpdateX509SVIDs(svids map[string]*X509SVID)

type X509WorkloadUpdate added in v1.16.0

type X509WorkloadUpdate struct {
	Identities       []X509Identity
	Bundle           *spiffebundle.Bundle
	FederatedBundles map[spiffeid.TrustDomain]*spiffebundle.Bundle
}

X509WorkloadUpdate is used to convey X509 workload information to cache subscribers.

func (*X509WorkloadUpdate) HasIdentity added in v1.16.0

func (u *X509WorkloadUpdate) HasIdentity() bool

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL