Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,25 @@ import "teleport/legacy/types/types.proto";

option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/recordingencryption/v1;recordingencryptionv1";

// The possible states a KeyPair can be in.
enum KeyPairState {
// Unspecified value
KEY_PAIR_STATE_UNSPECIFIED = 0;
// Represents an active key.
KEY_PAIR_STATE_ACTIVE = 1;
// Represents a key in the process of being rotated.
KEY_PAIR_STATE_ROTATING = 2;
// Represents a key being rotated in that is inaccessible to at least one
// auth server.
KEY_PAIR_STATE_INACCESSIBLE = 3;
}

// A key pair used with age to wrap and unwrap file keys for session recording encryption.
message KeyPair {
// A key pair used with age to wrap and unwrap file keys for session recording encryption.
types.EncryptionKeyPair key_pair = 1;
// The current state of the key pair.
KeyPairState state = 2;
}

// RecordingEncryptionSpec contains the active key set for encrypted session recording.
Expand All @@ -51,3 +66,26 @@ message RecordingEncryption {
RecordingEncryptionSpec spec = 5;
RecordingEncryptionStatus status = 6;
}

// A rotated key pair previously used with age to wrap and unwrap file keys for session recording
// encryption.
message RotatedKeySpec {
// The rotated key pair previously used with age to wrap and unwrap file keys for session recording
// encryption.
types.EncryptionKeyPair encryption_key_pair = 2;
}

// The empty status of a RotatedKey.
message RotatedKeyStatus {}

// A previously rotated encryption key for session recordings kept for future replay. The metadata.name
// is expected to be the fingerprint of the public key contained in the spec, which is a hex encoded
// SHA256 hash of its PKIX form.
message RotatedKey {
Comment thread
Joerger marked this conversation as resolved.
string kind = 1;
string sub_kind = 2;
string version = 3;
teleport.header.v1.Metadata metadata = 4;
RotatedKeySpec spec = 5;
RotatedKeyStatus status = 6;
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ syntax = "proto3";
package teleport.recordingencryption.v1;

import "google/protobuf/timestamp.proto";
import "teleport/recordingencryption/v1/recording_encryption.proto";

option go_package = "github.com/gravitational/teleport/api/gen/proto/go/teleport/recordingencryption/v1;recordingencryptionv1";

Expand All @@ -29,6 +30,15 @@ service RecordingEncryptionService {
rpc UploadPart(UploadPartRequest) returns (UploadPartResponse);
// CompleteUploadRequest marks a multipart upload as complete.
rpc CompleteUpload(CompleteUploadRequest) returns (CompleteUploadResponse);

// RotateKey rotates the key pair used for encrypting session recording data.
rpc RotateKey(RotateKeyRequest) returns (RotateKeyResponse);
// GetRotationState returns whether or not a rotation is in progress.
rpc GetRotationState(GetRotationStateRequest) returns (GetRotationStateResponse);
// CompleteRotation moves rotated keys out of the active set.
rpc CompleteRotation(CompleteRotationRequest) returns (CompleteRotationResponse);
// RollbackRotation removes active keys and reverts rotating keys back to being active.
rpc RollbackRotation(RollbackRotationRequest) returns (RollbackRotationResponse);
}

// The handle to an upload for an encrypted session.
Expand Down Expand Up @@ -86,5 +96,44 @@ message CompleteUploadRequest {
repeated Part parts = 2;
}

// CompleteUploadResponse is the empty return value of a CompleteUpload request.
// The body of a CompleteUpload request.
message CompleteUploadResponse {}

// The body of a RotateKey request.
message RotateKeyRequest {}

// The return value of a RotateKey request.
message RotateKeyResponse {}

// The body of a GetRotationState request.
message GetRotationStateRequest {
int32 page_size = 1;
string page_token = 2;
}

// A public key fingerprint coupled with its current state.
message FingerprintWithState {
// A fingerprint identifying the public key of a KeyPair.
string fingerprint = 1;
// The state associated with the identified KeyPair.
v1.KeyPairState state = 2;
}

// The current state of all active encryption key pairs.
message GetRotationStateResponse {
string next_page_token = 1;
// The state of all active encryption key pairs.
repeated FingerprintWithState key_pair_states = 2;
}

// The body of a CompleteRotation request.
message CompleteRotationRequest {}

// The return value of a CompleteRotation request.
message CompleteRotationResponse {}

// The body of a RollbackRotation request.
message RollbackRotationRequest {}

// The return value of a RollbackRotation request
message RollbackRotationResponse {}
3 changes: 3 additions & 0 deletions api/types/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,9 @@ const (
// KindRecordingEncryption is the collection of active session recording encryption keys.
KindRecordingEncryption = "recording_encryption"

// KindRotatedKey is a previously rotated session recording encryption key kept for future replay.
KindRotatedKey = "rotated_key"

// MetaNameSessionRecordingConfig is the exact name of the singleton resource for
// session recording configuration.
MetaNameSessionRecordingConfig = "session-recording-config"
Expand Down
4 changes: 2 additions & 2 deletions lib/auth/recordingencryption/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
"crypto"
"crypto/sha256"
"crypto/x509"
"encoding/base64"
"encoding/hex"
"iter"
"log/slog"
"slices"
Expand Down Expand Up @@ -531,7 +531,7 @@ func Fingerprint(pubKey crypto.PublicKey) (string, error) {
}

fp := sha256.Sum256(derPub)
return base64.StdEncoding.EncodeToString(fp[:]), nil
return hex.EncodeToString(fp[:]), nil
}

// fingerprints a public RSA key encoded as PEM-wrapped PKIX.
Expand Down
2 changes: 2 additions & 0 deletions lib/services/local/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,8 @@ func (e *EventsService) NewWatcher(ctx context.Context, watch types.Watch) (type
parser = newHealthCheckConfigParser()
case types.KindRecordingEncryption:
parser = newRecordingEncryptionParser()
case types.KindRotatedKey:
parser = newRotatedKeyParser()
case types.KindRelayServer:
parser = newRelayServerParser()
default:
Expand Down
Loading
Loading