Skip to content

Commit 4fc9628

Browse files
committed
adding cache for RecordingEncryption
1 parent 5d49ccd commit 4fc9628

File tree

13 files changed

+264
-8
lines changed

13 files changed

+264
-8
lines changed

api/client/events.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
notificationsv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/notifications/v1"
3131
presencev1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/presence/v1"
3232
provisioningv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/provisioning/v1"
33+
recordingencryptionv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/recordingencryption/v1"
3334
accessv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/scopes/access/v1"
3435
userprovisioningpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/userprovisioning/v2"
3536
usertasksv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/usertasks/v1"
@@ -157,6 +158,10 @@ func EventToGRPC(in types.Event) (*proto.Event, error) {
157158
out.Resource = &proto.Event_WorkloadIdentityX509Revocation{
158159
WorkloadIdentityX509Revocation: r.UnwrapT(),
159160
}
161+
case types.Resource153UnwrapperT[*recordingencryptionv1.RecordingEncryption]:
162+
out.Resource = &proto.Event_RecordingEncryption{
163+
RecordingEncryption: r.UnwrapT(),
164+
}
160165
case types.Resource153UnwrapperT[*healthcheckconfigv1.HealthCheckConfig]:
161166
out.Resource = &proto.Event_HealthCheckConfig{
162167
HealthCheckConfig: r.UnwrapT(),
@@ -660,6 +665,9 @@ func EventFromGRPC(in *proto.Event) (*types.Event, error) {
660665
} else if r := in.GetRelayServer(); r != nil {
661666
out.Resource = types.ProtoResource153ToLegacy(r)
662667
return &out, nil
668+
} else if r := in.GetRecordingEncryption(); r != nil {
669+
out.Resource = types.ProtoResource153ToLegacy(r)
670+
return &out, nil
663671
} else {
664672
return nil, trace.BadParameter("received unsupported resource %T", in.Resource)
665673
}

api/client/proto/event.pb.go

Lines changed: 29 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/proto/teleport/legacy/client/proto/event.proto

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import "teleport/machineid/v1/federation.proto";
3232
import "teleport/notifications/v1/notifications.proto";
3333
import "teleport/presence/v1/relay_server.proto";
3434
import "teleport/provisioning/v1/provisioning.proto";
35+
import "teleport/recordingencryption/v1/recording_encryption.proto";
3536
import "teleport/scopes/access/v1/assignment.proto";
3637
import "teleport/scopes/access/v1/role.proto";
3738
import "teleport/secreports/v1/secreports.proto";
@@ -227,5 +228,7 @@ message Event {
227228
// ScopedRoleAssignment is an assignment of one or more scoped roles to a user.
228229
teleport.scopes.access.v1.ScopedRoleAssignment ScopedRoleAssignment = 81;
229230
teleport.presence.v1.RelayServer relay_server = 82;
231+
// RecordingEncryption is a resource for controlling session recording encryption.
232+
teleport.recordingencryption.v1.RecordingEncryption RecordingEncryption = 83;
230233
}
231234
}

lib/auth/accesspoint/accesspoint.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ type Config struct {
112112
PluginStaticCredentials services.PluginStaticCredentials
113113
GitServers services.GitServers
114114
HealthCheckConfig services.HealthCheckConfigReader
115+
RecordingEncryption services.RecordingEncryption
115116
}
116117

117118
func (c *Config) CheckAndSetDefaults() error {
@@ -213,6 +214,7 @@ func NewCache(cfg Config) (*cache.Cache, error) {
213214
GitServers: cfg.GitServers,
214215
HealthCheckConfig: cfg.HealthCheckConfig,
215216
BotInstanceService: cfg.BotInstance,
217+
RecordingEncryption: cfg.RecordingEncryption,
216218
}
217219

218220
return cache.New(cfg.Setup(cacheCfg))

lib/auth/init.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ type VersionStorage interface {
9191
type RecordingEncryptionManager interface {
9292
services.RecordingEncryption
9393
recordingencryption.DecryptionKeyFinder
94+
SetCache(cache recordingencryption.Cache)
9495
}
9596

9697
// InitConfig is auth server init config

lib/auth/recordingencryption/manager.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,24 @@ type KeyStore interface {
4646
GetDecrypter(ctx context.Context, keyPair *types.EncryptionKeyPair) (crypto.Decrypter, error)
4747
}
4848

49+
// A Cache fetches a cached *recordingencryptionv1.RecordingEncryption
50+
type Cache interface {
51+
GetRecordingEncryption(context.Context) (*recordingencryptionv1.RecordingEncryption, error)
52+
}
53+
4954
// ManagerConfig captures all of the dependencies required to instantiate a Manager.
5055
type ManagerConfig struct {
5156
Backend services.RecordingEncryption
5257
ClusterConfig services.ClusterConfigurationInternal
5358
KeyStore KeyStore
59+
Cache Cache
5460
Logger *slog.Logger
5561
LockConfig backend.RunWhileLockedConfig
5662
}
5763

5864
// NewManager returns a new Manager using the given ManagerConfig.
5965
func NewManager(cfg ManagerConfig) (*Manager, error) {
66+
6067
switch {
6168
case cfg.Backend == nil:
6269
return nil, trace.BadParameter("backend is required")
@@ -70,10 +77,15 @@ func NewManager(cfg ManagerConfig) (*Manager, error) {
7077
cfg.Logger = slog.With(teleport.ComponentKey, "recording-encryption-manager")
7178
}
7279

80+
if cfg.Cache == nil {
81+
cfg.Cache = cfg.Backend
82+
}
83+
7384
return &Manager{
7485
RecordingEncryption: cfg.Backend,
7586
ClusterConfigurationInternal: cfg.ClusterConfig,
7687

88+
cache: cfg.Cache,
7789
keyStore: cfg.KeyStore,
7890
lockConfig: cfg.LockConfig,
7991
logger: cfg.Logger,
@@ -87,6 +99,7 @@ type Manager struct {
8799
services.RecordingEncryption
88100
services.ClusterConfigurationInternal
89101

102+
cache Cache
90103
logger *slog.Logger
91104
lockConfig backend.RunWhileLockedConfig
92105
keyStore KeyStore
@@ -164,6 +177,11 @@ func (m *Manager) UpsertSessionRecordingConfig(ctx context.Context, cfg types.Se
164177
return sessionRecordingConfig, trace.Wrap(err)
165178
}
166179

180+
// SetCache overwrites the configured Cache implementation
181+
func (m *Manager) SetCache(cache Cache) {
182+
m.cache = cache
183+
}
184+
167185
// ensureActiveRecordingEncryption returns the configured RecordingEncryption resource if it exists with active keys. If it does not,
168186
// then the resource will be created or updated with a new active keypair. The bool return value indicates whether or not
169187
// a new pair was provisioned.
@@ -367,7 +385,7 @@ func (m *Manager) searchActiveKeys(ctx context.Context, activeKeys []*recordinge
367385

368386
// FindDecryptionKey returns the first accessible decryption key that matches one of the given public keys.
369387
func (m *Manager) FindDecryptionKey(ctx context.Context, publicKeys ...[]byte) (*types.EncryptionKeyPair, error) {
370-
encryption, err := m.RecordingEncryption.GetRecordingEncryption(ctx)
388+
encryption, err := m.cache.GetRecordingEncryption(ctx)
371389
if err != nil {
372390
return nil, trace.Wrap(err)
373391
}

lib/auth/recordingencryption/manager_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ func newManagerConfig(t *testing.T, bk backend.Backend, keyType types.PrivateKey
134134

135135
return recordingencryption.ManagerConfig{
136136
Backend: recordingEncryptionService,
137+
Cache: recordingEncryptionService,
137138
ClusterConfig: clusterConfigService,
138139
KeyStore: &fakeKeyStore{keyType: keyType},
139140
Logger: utils.NewSlogLoggerForTests(),

lib/cache/cache.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ func ForAuth(cfg Config) Config {
211211
{Kind: types.KindHealthCheckConfig},
212212
{Kind: types.KindRelayServer},
213213
{Kind: types.KindBotInstance},
214+
{Kind: types.KindRecordingEncryption},
214215
}
215216
cfg.QueueSize = defaults.AuthQueueSize
216217
// We don't want to enable partial health for auth cache because auth uses an event stream
@@ -747,6 +748,8 @@ type Config struct {
747748
HealthCheckConfig services.HealthCheckConfigReader
748749
// BotInstanceService is the upstream service that we're caching
749750
BotInstanceService services.BotInstance
751+
// RecordingEncryption manages state surrounding session recording encryption
752+
RecordingEncryption services.RecordingEncryption
750753
}
751754

752755
// CheckAndSetDefaults checks parameters and sets default values

lib/cache/cache_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import (
5555
notificationsv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/notifications/v1"
5656
presencev1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/presence/v1"
5757
provisioningv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/provisioning/v1"
58+
recordingencryptionv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/recordingencryption/v1"
5859
accessv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/scopes/access/v1"
5960
userprovisioningpb "github.com/gravitational/teleport/api/gen/proto/go/teleport/userprovisioning/v2"
6061
usertasksv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/usertasks/v1"
@@ -150,6 +151,7 @@ type testPack struct {
150151
workloadIdentity *local.WorkloadIdentityService
151152
healthCheckConfig *local.HealthCheckConfigService
152153
botInstanceService *local.BotInstanceService
154+
recordingEncryption *local.RecordingEncryptionService
153155
}
154156

155157
// testFuncs are functions to support testing an object in a cache.
@@ -433,6 +435,11 @@ func newPackWithoutCache(dir string, opts ...packOption) (*testPack, error) {
433435
return nil, trace.Wrap(err)
434436
}
435437

438+
p.recordingEncryption, err = local.NewRecordingEncryptionService(p.backend)
439+
if err != nil {
440+
return nil, trace.Wrap(err)
441+
}
442+
436443
return p, nil
437444
}
438445

@@ -490,6 +497,7 @@ func newPack(dir string, setupConfig func(c Config) Config, opts ...packOption)
490497
HealthCheckConfig: p.healthCheckConfig,
491498
WorkloadIdentity: p.workloadIdentity,
492499
BotInstanceService: p.botInstanceService,
500+
RecordingEncryption: p.recordingEncryption,
493501
MaxRetryPeriod: 200 * time.Millisecond,
494502
EventsC: p.eventsC,
495503
}))
@@ -759,6 +767,7 @@ func TestCompletenessInit(t *testing.T) {
759767
AutoUpdateService: p.autoUpdateService,
760768
ProvisioningStates: p.provisioningStates,
761769
WorkloadIdentity: p.workloadIdentity,
770+
RecordingEncryption: p.recordingEncryption,
762771
MaxRetryPeriod: 200 * time.Millisecond,
763772
IdentityCenter: p.identityCenter,
764773
PluginStaticCredentials: p.pluginStaticCredentials,
@@ -849,6 +858,7 @@ func TestCompletenessReset(t *testing.T) {
849858
IdentityCenter: p.identityCenter,
850859
PluginStaticCredentials: p.pluginStaticCredentials,
851860
WorkloadIdentity: p.workloadIdentity,
861+
RecordingEncryption: p.recordingEncryption,
852862
MaxRetryPeriod: 200 * time.Millisecond,
853863
EventsC: p.eventsC,
854864
GitServers: p.gitServers,
@@ -1007,6 +1017,7 @@ func TestListResources_NodesTTLVariant(t *testing.T) {
10071017
IdentityCenter: p.identityCenter,
10081018
PluginStaticCredentials: p.pluginStaticCredentials,
10091019
WorkloadIdentity: p.workloadIdentity,
1020+
RecordingEncryption: p.recordingEncryption,
10101021
MaxRetryPeriod: 200 * time.Millisecond,
10111022
EventsC: p.eventsC,
10121023
neverOK: true, // ensure reads are never healthy
@@ -1106,6 +1117,7 @@ func initStrategy(t *testing.T) {
11061117
IdentityCenter: p.identityCenter,
11071118
PluginStaticCredentials: p.pluginStaticCredentials,
11081119
WorkloadIdentity: p.workloadIdentity,
1120+
RecordingEncryption: p.recordingEncryption,
11091121
MaxRetryPeriod: 200 * time.Millisecond,
11101122
EventsC: p.eventsC,
11111123
GitServers: p.gitServers,
@@ -1867,6 +1879,7 @@ func TestCacheWatchKindExistsInEvents(t *testing.T) {
18671879
types.KindPluginStaticCredentials: &types.PluginStaticCredentialsV1{},
18681880
types.KindGitServer: &types.ServerV2{},
18691881
types.KindWorkloadIdentity: types.Resource153ToLegacy(newWorkloadIdentity("some_identifier")),
1882+
types.KindRecordingEncryption: types.Resource153ToLegacy(newRecordingEncryption()),
18701883
types.KindHealthCheckConfig: types.Resource153ToLegacy(newHealthCheckConfig(t, "some-name")),
18711884
scopedrole.KindScopedRole: types.Resource153ToLegacy(&accessv1.ScopedRole{}),
18721885
scopedrole.KindScopedRoleAssignment: types.Resource153ToLegacy(&accessv1.ScopedRoleAssignment{}),
@@ -1911,6 +1924,8 @@ func TestCacheWatchKindExistsInEvents(t *testing.T) {
19111924
require.Empty(t, cmp.Diff(resource.(types.Resource153UnwrapperT[*autoupdate.AutoUpdateVersion]).UnwrapT(), uw.UnwrapT(), protocmp.Transform()))
19121925
case types.Resource153UnwrapperT[*autoupdate.AutoUpdateConfig]:
19131926
require.Empty(t, cmp.Diff(resource.(types.Resource153UnwrapperT[*autoupdate.AutoUpdateConfig]).UnwrapT(), uw.UnwrapT(), protocmp.Transform()))
1927+
case types.Resource153UnwrapperT[*recordingencryptionv1.RecordingEncryption]:
1928+
require.Empty(t, cmp.Diff(resource.(types.Resource153UnwrapperT[*recordingencryptionv1.RecordingEncryption]).UnwrapT(), uw.UnwrapT(), protocmp.Transform()))
19141929
case types.Resource153UnwrapperT[*userprovisioningpb.StaticHostUser]:
19151930
require.Empty(t, cmp.Diff(resource.(types.Resource153UnwrapperT[*userprovisioningpb.StaticHostUser]).UnwrapT(), uw.UnwrapT(), protocmp.Transform()))
19161931
case types.Resource153UnwrapperT[*machineidv1.SPIFFEFederation]:

0 commit comments

Comments
 (0)