Skip to content

Commit

Permalink
Use CloudAnonymizationKey if present
Browse files Browse the repository at this point in the history
  • Loading branch information
michellescripts committed Oct 17, 2024
1 parent 22edf09 commit b42d2e7
Show file tree
Hide file tree
Showing 6 changed files with 1,039 additions and 942 deletions.
1,926 changes: 992 additions & 934 deletions api/client/proto/authservice.pb.go

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions api/proto/teleport/legacy/client/proto/authservice.proto
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,8 @@ message Features {
// NOTE: this flag is used to signal that Access Monitoring is *enabled* on a cluster.
// *Access* to the feature is gated on the `AccessMonitoring` entitlement.
bool AccessMonitoringConfigured = 36;
// cloud_anonymization_key is a hash of the Salesforce ID used to anonymize usage events
bytes cloud_anonymization_key = 37 [json_name = "cloudAnonymizationKey"];
}

// EntitlementInfo is the state and limits of a particular entitlement
Expand Down
5 changes: 4 additions & 1 deletion lib/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -1897,7 +1897,10 @@ func (a *Server) GetAnonymizationKey(ctx context.Context, opts ...services.Marsh
return a.GetClusterID(ctx, opts...)
}

return string(a.license.AnonymizationKey), nil
return cmp.Or(
string(modules.GetModules().Features().CloudAnonymizationKey),
string(a.license.AnonymizationKey),
), nil
}

// GetDomainName returns the domain name that identifies this authority server.
Expand Down
3 changes: 3 additions & 0 deletions lib/modules/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ type Features struct {
SupportType proto.SupportType
// Entitlements reflect Cloud Entitlements including access and limits
Entitlements map[entitlements.EntitlementKind]EntitlementInfo
// CloudAnonymizationKey is the key used to anonymize usage events in a cluster. If not present, defaults to
// cluster id.Only applicable for Cloud hosted customers, not self-hosted.
CloudAnonymizationKey []byte

// todo (michellescripts) have the following fields evaluated for deprecation, consolidation, or fetch from Cloud
// AdvancedAccessWorkflows is currently set to the value of the Cloud Access Requests entitlement
Expand Down
39 changes: 32 additions & 7 deletions lib/usagereporter/teleport/aggregating/reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ const (
rollbackGrace = time.Minute
reportTTL = 60 * 24 * time.Hour

checkInterval = time.Minute
checkInterval = time.Minute
anonymizationKeyRefreshInterval = 5 * time.Minute
)

// ReporterConfig contains the configuration for a [Reporter].
Expand All @@ -67,8 +68,8 @@ type ReporterConfig struct {
// HostID is the host ID of the current Teleport instance, added to reports
// for auditing purposes. Required.
HostID string
// AnonymizationKey is the key used to anonymize data user or resource names. Optional.
AnonymizationKey string
// GetAnonymizationKey returns the key used to anonymize data user or resource names. Required.
GetAnonymizationKey func(context.Context) (string, error)
}

// CheckAndSetDefaults checks the [ReporterConfig] for validity, returning nil
Expand All @@ -87,8 +88,8 @@ func (cfg *ReporterConfig) CheckAndSetDefaults() error {
if cfg.HostID == "" {
return trace.BadParameter("missing HostID")
}
if cfg.AnonymizationKey == "" {
return trace.BadParameter("missing AnonymizationKey")
if cfg.GetAnonymizationKey == nil {
return trace.BadParameter("missing GetAnonymizationKey")
}

if cfg.Logger == nil {
Expand All @@ -105,7 +106,12 @@ func NewReporter(ctx context.Context, cfg ReporterConfig) (*Reporter, error) {
return nil, trace.Wrap(err)
}

anonymizer, err := utils.NewHMACAnonymizer(cfg.AnonymizationKey)
anonymizationKey, err := cfg.GetAnonymizationKey(ctx)
if err != nil {
return nil, trace.Wrap(err)
}

anonymizer, err := utils.NewHMACAnonymizer(anonymizationKey)
if err != nil {
return nil, trace.Wrap(err)
}
Expand All @@ -125,7 +131,8 @@ func NewReporter(ctx context.Context, cfg ReporterConfig) (*Reporter, error) {
clusterName: anonymizer.AnonymizeNonEmpty(cfg.ClusterName.GetClusterName()),
hostID: anonymizer.AnonymizeNonEmpty(cfg.HostID),

baseCancel: baseCancel,
baseCancel: baseCancel,
getAnonymizationKey: cfg.GetAnonymizationKey,
}

go r.run(baseCtx)
Expand Down Expand Up @@ -161,6 +168,8 @@ type Reporter struct {
// ingested, if non-nil, received events after being added to the aggregated
// data. Used in tests.
ingested chan usagereporter.Anonymizable
// getAnonymizationKey returns the key used to anonymize data user or resource names. Required.
getAnonymizationKey func(context.Context) (string, error)
}

var _ usagereporter.GracefulStopper = (*Reporter)(nil)
Expand Down Expand Up @@ -240,6 +249,9 @@ func (r *Reporter) run(ctx context.Context) {
ticker := r.clock.NewTicker(checkInterval)
defer ticker.Stop()

anonymizationKeyChecker := r.clock.NewTicker(anonymizationKeyRefreshInterval)
defer anonymizationKeyChecker.Stop()

userActivityStartTime := r.clock.Now().UTC().Truncate(userActivityReportGranularity)
userActivityWindowStart := userActivityStartTime.Add(-rollbackGrace)
userActivityWindowEnd := userActivityStartTime.Add(userActivityReportGranularity)
Expand Down Expand Up @@ -305,6 +317,19 @@ Ingest:
select {
case <-ticker.Chan():
case ae = <-r.ingest:
case <-anonymizationKeyChecker.Chan():
updatedKey, err := r.getAnonymizationKey(ctx)
if err != nil {
r.logger.WarnContext(ctx, "Failed to get anonymization key: %v", err)
continue
}

anonymizer, err := utils.NewHMACAnonymizer(updatedKey)
if err != nil {
r.logger.WarnContext(ctx, "Failed to create anonymizer: %v", err)
continue
}
r.anonymizer = anonymizer

case <-ctx.Done():
r.closingOnce.Do(func() { close(r.closing) })
Expand Down
6 changes: 6 additions & 0 deletions lib/web/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
package web

import (
"bytes"

"github.com/gravitational/teleport/api/client/proto"
"github.com/gravitational/teleport/entitlements"
)
Expand All @@ -30,6 +32,10 @@ func (h *Handler) SetClusterFeatures(features proto.Features) {
h.Mutex.Lock()
defer h.Mutex.Unlock()

if !bytes.Equal(h.clusterFeatures.CloudAnonymizationKey, features.CloudAnonymizationKey) {
h.log.Info("Received new cloud anonymization key from server")
}

entitlements.BackfillFeatures(&features)
h.clusterFeatures = features
}
Expand Down

0 comments on commit b42d2e7

Please sign in to comment.