Skip to content

Commit 89584dd

Browse files
authored
Add ListValidatedMFAChallenges RPC to MFA service for leaf cluster resource replication (#63773)
* Try impl leaf cluster replication using pure watcher API. Signed-off-by: Chris Thach <chris.thach@goteleport.com> * Add ValidatedMFAChallenge replication to leaf clusters. Signed-off-by: Chris Thach <chris.thach@goteleport.com> * Remove changes unrelated to MFA proto/gRPC updates. Signed-off-by: Chris Thach <chris.thach@goteleport.com> * Add optional filtering. Signed-off-by: Chris Thach <chris.thach@goteleport.com> * Authorize local proxy identities only. Remove cluster exists check. Signed-off-by: Chris Thach <chris.thach@goteleport.com> * Make target cluster primary key in storing resource. Signed-off-by: Chris Thach <chris.thach@goteleport.com> * Remove unnecessary filter. Signed-off-by: Chris Thach <chris.thach@goteleport.com> --------- Signed-off-by: Chris Thach <chris.thach@goteleport.com>
1 parent 0652d40 commit 89584dd

File tree

11 files changed

+1578
-274
lines changed

11 files changed

+1578
-274
lines changed

api/gen/proto/go/teleport/mfa/v1/service.pb.go

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

api/gen/proto/go/teleport/mfa/v1/service_grpc.pb.go

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

api/gen/proto/go/teleport/mfa/v1/validated_challenge.pb.go

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

api/proto/teleport/mfa/v1/service.proto

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ service MFAService {
3030
// ValidateSessionChallenge validates the MFA challenge response for a user session and stores the validated response
3131
// in the backend.
3232
rpc ValidateSessionChallenge(ValidateSessionChallengeRequest) returns (ValidateSessionChallengeResponse);
33+
// ListValidatedMFAChallenges lists validated MFA challenges that have been created for all user sessions. This is
34+
// intended to be used by the reverse tunnel server to watch for new validated challenges that need to be replicated
35+
// for SSH session establishment in leaf clusters.
36+
rpc ListValidatedMFAChallenges(ListValidatedMFAChallengesRequest) returns (ListValidatedMFAChallengesResponse);
3337
// ReplicateValidatedMFAChallenge replicates a validated MFA challenge from root cluster to leaf cluster for
3438
// verification during SSH session establishment. The reverse tunnel server watches for validated challenges in the
3539
// root cluster and invokes this RPC on the leaf cluster. This is a NOOP when invoked in the root cluster.
@@ -74,6 +78,32 @@ message ValidateSessionChallengeRequest {
7478
// ValidateSessionChallengeResponse is the response message for ValidateSessionChallenge.
7579
message ValidateSessionChallengeResponse {}
7680

81+
// ListValidatedMFAChallengesFilter is used to filter validated MFA challenges in ListValidatedMFAChallengesRequest.
82+
message ListValidatedMFAChallengesFilter {
83+
// If set, only return validated MFA challenges for the specified target cluster.
84+
optional string target_cluster = 1;
85+
}
86+
87+
// ListValidatedMFAChallengesRequest is the request message for ListValidatedMFAChallenges.
88+
message ListValidatedMFAChallengesRequest {
89+
// The maximum number of items to return. The server may impose a different page size at its discretion.
90+
int32 page_size = 1;
91+
// The next_page_token value returned from a previous List request, if any.
92+
string page_token = 2;
93+
// Collection of fields to filter challenges by. Challenges must match all filter fields to be included in the
94+
// results. If unset, no filtering is performed and all validated MFA challenges are returned (up to the page size
95+
// limit).
96+
ListValidatedMFAChallengesFilter filter = 3;
97+
}
98+
99+
// ListValidatedMFAChallengesResponse is the response message for ListValidatedMFAChallenges.
100+
message ListValidatedMFAChallengesResponse {
101+
// List of validated MFA challenges that have been created for user sessions.
102+
repeated ValidatedMFAChallenge validated_challenges = 1;
103+
// Token to retrieve the next page of results, or empty if there are no more results exist.
104+
string next_page_token = 2;
105+
}
106+
77107
// ReplicateValidatedMFAChallengeRequest is the request message for ReplicateValidatedMFAChallenge.
78108
message ReplicateValidatedMFAChallengeRequest {
79109
// Resource name for the issued challenge. Must match the AuthenticateChallenge.name in order to find the correct

api/proto/teleport/mfa/v1/validated_challenge.proto

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ message ValidatedMFAChallengeSpec {
4242
string source_cluster = 2;
4343
// Name of the cluster where the SSH session is being established and this resource is intended for.
4444
string target_cluster = 3;
45+
// Username of the Teleport user for whom the challenge was issued. This should be the Teleport username (not the SSH
46+
// login name) and must correspond to a user in the cluster specified to source_cluster.
47+
string username = 4;
4548
}
4649

4750
// SessionIdentifyingPayload contains a value that uniquely identifies a user's session. It must be computed by the

lib/auth/mfa/mfav1/mocks_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,13 @@ type mockMFAService struct {
145145

146146
createValidatedMFAChallengeError error
147147
getValidatedMFAChallengeError error
148+
149+
listValidatedMFAChallenges []*mfav1.ValidatedMFAChallenge
150+
listValidatedMFAChallengesToken string
151+
listValidatedMFAChallengesError error
152+
listValidatedMFAChallengesPageSize int32
153+
listValidatedMFAChallengesPageToken string
154+
listValidatedMFAChallengesTarget string
148155
}
149156

150157
func (m *mockMFAService) CreateValidatedMFAChallenge(
@@ -178,3 +185,22 @@ func (m *mockMFAService) GetValidatedMFAChallenge(
178185

179186
return m.chal, nil
180187
}
188+
189+
func (m *mockMFAService) ListValidatedMFAChallenges(
190+
_ context.Context,
191+
pageSize int32,
192+
pageToken string,
193+
targetCluster string,
194+
) ([]*mfav1.ValidatedMFAChallenge, string, error) {
195+
if m.listValidatedMFAChallengesError != nil {
196+
return nil, "", m.listValidatedMFAChallengesError
197+
}
198+
199+
m.mu.Lock()
200+
defer m.mu.Unlock()
201+
m.listValidatedMFAChallengesPageSize = pageSize
202+
m.listValidatedMFAChallengesPageToken = pageToken
203+
m.listValidatedMFAChallengesTarget = targetCluster
204+
205+
return m.listValidatedMFAChallenges, m.listValidatedMFAChallengesToken, nil
206+
}

0 commit comments

Comments
 (0)