@@ -107,11 +107,104 @@ message TokenInit {
107107 ClientParams client_params = 1 ;
108108}
109109
110+ // BoundKeypairInit is sent from the client in response to the ServerInit
111+ // message for the bound keypair join method.
112+ // The server is expected to respond with a BoundKeypairChallenge.
113+ //
114+ // The bound keypair method join flow is:
115+ // 1. client->server: ClientInit
116+ // 2. server->client: ServerInit
117+ // 3. client->server: BoundKeypairInit
118+ // 4. server->client: BoundKeypairChallenge
119+ // 5. client->server: BoundKeypairChallengeSolution
120+ // (optional additional steps if keypair rotation is required)
121+ // server->client: BoundKeypairRotationRequest
122+ // client->server: BoundKeypairRotationResponse
123+ // server->client: BoundKeypairChallenge
124+ // client->server: BoundKeypairChallengeSolution
125+ // 6. server->client: Result containing BoundKeypairResult
126+ message BoundKeypairInit {
127+ // ClientParams holds parameters for the specific type of client trying to join.
128+ ClientParams client_params = 1 ;
129+ // If set, attempts to bind a new keypair using an initial join secret.
130+ // Any value set here will be ignored if a keypair is already bound.
131+ string initial_join_secret = 2 ;
132+ // A document signed by Auth containing join state parameters from the
133+ // previous join attempt. Not required on initial join; required on all
134+ // subsequent joins.
135+ bytes previous_join_state = 3 ;
136+ }
137+
138+ // BoundKeypairChallenge is a challenge issued by the server that joining
139+ // clients are expected to complete.
140+ // The client is expected to respond with a BoundKeypairChallengeSolution.
141+ message BoundKeypairChallenge {
142+ // The desired public key corresponding to the private key that should be used
143+ // to sign this challenge, in SSH authorized keys format.
144+ bytes public_key = 1 ;
145+ // A challenge to sign with the requested public key. During keypair rotation,
146+ // a second challenge will be provided to verify the new keypair before certs
147+ // are returned.
148+ string challenge = 2 ;
149+ }
150+
151+ // BoundKeypairChallengeSolution is sent from the client in response to the
152+ // BoundKeypairChallenge.
153+ // The server is expected to respond with either a Result or a
154+ // BoundKeypairRotationRequest.
155+ message BoundKeypairChallengeSolution {
156+ // A solution to a challenge from the server. This generated by signing the
157+ // challenge as a JWT using the keypair associated with the requested public
158+ // key.
159+ bytes solution = 1 ;
160+ }
161+
162+ // BoundKeypairRotationRequest is sent by the server in response to a
163+ // BoundKeypairChallenge when a keypair rotation is required. It acts like an
164+ // additional challenge, the client is expected to respond with a
165+ // BoundKeypairRotationResponse.
166+ message BoundKeypairRotationRequest {
167+ // The signature algorithm suite in use by the cluster.
168+ string signature_algorithm_suite = 1 ;
169+ }
170+
171+ // BoundKeypairRotationResponse is sent by the client in response to a
172+ // BoundKeypairRotationRequest from the server.
173+ // The server is expected to respond with an additional BoundKeypairChallenge
174+ // for the new key.
175+ message BoundKeypairRotationResponse {
176+ // The public key to be registered with auth. Clients should expect a
177+ // subsequent challenge against this public key to be sent. This is encoded in
178+ // SSH authorized keys format.
179+ bytes public_key = 1 ;
180+ }
181+
182+ // BoundKeypairResult holds additional result parameters relevant to the bound
183+ // keypair join method.
184+ message BoundKeypairResult {
185+ // A signed join state document to be provided on the next join attempt.
186+ bytes join_state = 2 ;
187+ // The public key registered with Auth at the end of the joining ceremony.
188+ // After a successful keypair rotation, this should reflect the newly
189+ // registered public key. This is encoded in SSH authorized keys format.
190+ bytes public_key = 3 ;
191+ }
192+
193+ // ChallengeSolution holds a solution to a challenge issued by the server.
194+ message ChallengeSolution {
195+ oneof payload {
196+ BoundKeypairChallengeSolution bound_keypair_challenge_solution = 1 ;
197+ BoundKeypairRotationResponse bound_keypair_rotation_response = 2 ;
198+ }
199+ }
200+
110201// JoinRequest is the message type sent from the joining client to the server.
111202message JoinRequest {
112203 oneof payload {
113204 ClientInit client_init = 1 ;
114205 TokenInit token_init = 2 ;
206+ BoundKeypairInit bound_keypair_init = 3 ;
207+ ChallengeSolution solution = 4 ;
115208 }
116209}
117210
@@ -126,7 +219,12 @@ message ServerInit {
126219}
127220
128221// Challenge is a challenge message sent from the server that the client must solve.
129- message Challenge {}
222+ message Challenge {
223+ oneof payload {
224+ BoundKeypairChallenge bound_keypair_challenge = 1 ;
225+ BoundKeypairRotationRequest bound_keypair_rotation_request = 2 ;
226+ }
227+ }
130228
131229// Result is the final message sent from the cluster back to the client, it
132230// contains the result of the joining process including the assigned host ID
@@ -164,6 +262,8 @@ message HostResult {
164262message BotResult {
165263 // Certificates holds issued certificates and cluster CAs.
166264 Certificates certificates = 1 ;
265+ // BoundKeypairResult holds extra result parameters relevant to the bound keypair join method.
266+ optional BoundKeypairResult bound_keypair_result = 2 ;
167267}
168268
169269// JoinResponse is the message type sent from the server to the joining client.
0 commit comments