Documentation
¶
Index ¶
- Constants
- type Bundle
- type BundleCache
- func (c *BundleCache) Bundle() *Bundle
- func (c *BundleCache) Bundles() map[spiffeid.TrustDomain]*Bundle
- func (c *BundleCache) GetX509BundleForTrustDomain(trustDomain spiffeid.TrustDomain) (*x509bundle.Bundle, error)
- func (c *BundleCache) SubscribeToBundleChanges() *BundleStream
- func (c *BundleCache) Update(bundles map[spiffeid.TrustDomain]*Bundle)
- type BundleStream
- func (b *BundleStream) Changes() chan struct{}
- func (b *BundleStream) Clone() *BundleStream
- func (b *BundleStream) HasNext() bool
- func (b *BundleStream) Next() map[spiffeid.TrustDomain]*Bundle
- func (b *BundleStream) Value() map[spiffeid.TrustDomain]*Bundle
- func (b *BundleStream) WaitNext() map[spiffeid.TrustDomain]*Bundle
- type CachedSVID
- type JWTSVIDCache
- func (c *JWTSVIDCache) CountJWTSVIDs() int
- func (c *JWTSVIDCache) GetJWTSVID(spiffeID spiffeid.ID, audience []string) (*client.JWTSVID, bool)
- func (c *JWTSVIDCache) SetJWTSVID(spiffeID spiffeid.ID, audience []string, svid *client.JWTSVID)
- func (c *JWTSVIDCache) TaintJWTSVIDs(ctx context.Context, taintedJWTAuthorities map[string]struct{})
- type LRUCache
- func (c *LRUCache[SVID, Update]) CountRecords() int
- func (c *LRUCache[SVID, Update]) CountSVIDs() int
- func (c *LRUCache[SVID, Update]) Entries() []*common.RegistrationEntry
- func (c *LRUCache[SVID, Update]) FetchWorkloadUpdate(selectors []*common.Selector) *Update
- func (c *LRUCache[SVID, Update]) GatherFederatedBundles(entries []*common.RegistrationEntry) map[spiffeid.TrustDomain]*spiffebundle.Bundle
- func (c *LRUCache[SVID, Update]) GetStaleEntries() []*StaleEntry
- func (c *LRUCache[SVID, Update]) MatchingRegistrationEntries(selectors []*common.Selector) []*common.RegistrationEntry
- func (c *LRUCache[SVID, Update]) NewSubscriber(selectors []*common.Selector) Subscriber[Update]
- func (c *LRUCache[SVID, Update]) SubscribeToWorkloadUpdates(ctx context.Context, selectors Selectors) (Subscriber[Update], error)
- func (c *LRUCache[SVID, Update]) SyncSVIDsWithSubscribers()
- func (c *LRUCache[SVID, Update]) UpdateEntries(update *UpdateEntries, ...)
- func (c *LRUCache[SVID, Update]) UpdateSVIDs(svids map[string]*SVID)
- type LRUCacheConfig
- type Selectors
- type StaleEntry
- type Subscriber
- type UpdateEntries
- type WITIdentity
- type WITLRUCache
- type WITLRUCacheConfig
- type WITSVID
- type WITWorkloadUpdate
- type X509Identity
- type X509LRUCacheConfig
- type X509SVID
- type X509SVIDLRUCache
- type X509WorkloadUpdate
Constants ¶
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 (*JWTSVIDCache) SetJWTSVID ¶
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.
- Size limit of SVID cache is a soft limit. If SVID has a subscriber present then that SVID is never removed from cache.
- 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.
- Last access timestamp for SVID cache entry is updated when a new subscriber is created
- 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 (*LRUCache[SVID, Update]) CountSVIDs ¶ added in v1.4.4
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 (*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 (*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
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 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) 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) 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