Skip to content

Start the proof of a join code (join listener only).

POST
/v1/join/pake
Code sample: Shell / cURL
curl --request POST \
--url https://stratum.example.com/v1/join/pake \
--header 'Content-Type: application/json' \
--data '{ "codeSelector": "4F", "ke1": "example" }'

. The joiner starts an OPAQUE exchange (RFC 9807) with its short join code as the password, over TLS 1.3 with its own client certificate; both sides bind it to the connection’s exporter. The answer (KE2) proves to the joiner that the listener holds the code, and names the cluster CA the joiner then pins. The joiner proves the code back with its KE3 in POST /v1/join/registrations or POST /v1/join/code-checks, on the same connection.

A selector no code holds gets an answer like any other, which no KE3 proves. Every answer counts as an attempt on its code (an answer lets the caller test one guess), and a proof takes it back: past 10 unproven attempts the code is burned. Refused: no client certificate (401), not TLS 1.3 (400), the cluster CA changed since the code was minted (401 JOIN_CODE_STALE), too many calls from one address (429).

Media typeapplication/json

The start of a join code’s proof: an OPAQUE (RFC 9807) exchange with the code as the password, bound to the TLS 1.3 connection by its exporter (EXPORTER-stratum-join-pake-v1, in the OPAQUE context).

object
codeSelector
required

The code’s first two characters, which pick the code.

string
>= 2 characters <= 2 characters

Example

4F
ke1
required

The OPAQUE KE1 message, base64.

string format: byte

The listener’s answer.

Media typeapplication/json

The listener’s answer to a PAKE start. The joiner checks ke2: it verifies only if the listener holds the code and answered on this very TLS connection. Then the joiner pins caFingerprint (which must be a CA in the connection’s chain that signed the listener’s certificate) and sends its KE3 with the call it proves.

object
session
required

Names the exchange in the proof. Valid for 2 minutes, once.

string
ke2
required

The OPAQUE KE2 message, base64.

string format: byte
caFingerprint
required

The cluster root CA’s SHA-256 (DER), as hex pairs.

string

Example

{
"session": "pk-4f7k2q9mabcdefgh",
"caFingerprint": "7D:9F:05:39:12:F6:D4:91:0A:1B:2C:3D:4E:5F:60:71:82:93:A4:B5:C6:D7:E8:F9:0A:1B:2C:3D:4E:5F:60:71"
}

Bad request.

Media typeapplication/problem+json
object
type
required
string format: uri
title
required
string
status
required
integer
>= 400 <= 599
detail
string
instance
string format: uri-reference
requestId
required
string
code
required
string
issues

The findings of a rejected IAM policy document (custom and resource policies).

Array<object>

One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.

object
code
required

The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.

string
statement
required

Index of the statement at fault; -1 for the document as a whole.

integer
>= -1
detail
required
string
action

The offending action, where one is at fault (ACTION_NOT_APPLICABLE).

string
errors

Field errors, for codes that carry them: each problem at its field (see FieldError). Documented on the responses that set it, e.g. approveNodeJoin’s INVALID_INPUT and JOIN_APPROVAL_REFUSED. Absent otherwise.

Array<object>

One field’s problem, the stage-2 installer API’s shape. field is the field’s path, message what is wrong with it.

object
field
required

The field’s path, e.g. links[0].interface, disks[1].confirm, mgmt.address or role; empty for the whole request.

string
message
required
string
details

Structured facts about the refusal, for codes that carry them. The shape is fixed per code and documented on the response that answers it, e.g. IMAGE_POOL_MISMATCH (see ImagePoolMismatchDetails) and IMAGE_IN_USE. Absent for codes that carry none.

object
key
additional properties
any

Example

{
"issues": [
{
"code": "ACTION_NOT_APPLICABLE",
"action": "compute:CreateVpc"
}
]
}

Missing or invalid token.

Media typeapplication/problem+json
object
type
required
string format: uri
title
required
string
status
required
integer
>= 400 <= 599
detail
string
instance
string format: uri-reference
requestId
required
string
code
required
string
issues

The findings of a rejected IAM policy document (custom and resource policies).

Array<object>

One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.

object
code
required

The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.

string
statement
required

Index of the statement at fault; -1 for the document as a whole.

integer
>= -1
detail
required
string
action

The offending action, where one is at fault (ACTION_NOT_APPLICABLE).

string
errors

Field errors, for codes that carry them: each problem at its field (see FieldError). Documented on the responses that set it, e.g. approveNodeJoin’s INVALID_INPUT and JOIN_APPROVAL_REFUSED. Absent otherwise.

Array<object>

One field’s problem, the stage-2 installer API’s shape. field is the field’s path, message what is wrong with it.

object
field
required

The field’s path, e.g. links[0].interface, disks[1].confirm, mgmt.address or role; empty for the whole request.

string
message
required
string
details

Structured facts about the refusal, for codes that carry them. The shape is fixed per code and documented on the response that answers it, e.g. IMAGE_POOL_MISMATCH (see ImagePoolMismatchDetails) and IMAGE_IN_USE. Absent for codes that carry none.

object
key
additional properties
any

Example

{
"issues": [
{
"code": "ACTION_NOT_APPLICABLE",
"action": "compute:CreateVpc"
}
]
}
WWW-Authenticate
string

Request rate limit exceeded. The API-boundary throttle caps request throughput per principal and per project; code is RATE_LIMITED (distinct from the quota engine’s QUOTA_EXCEEDED). The Retry-After header carries the seconds to wait. Applies to any authenticated endpoint — it is enforced by middleware, not per-path.

Media typeapplication/problem+json
object
type
required
string format: uri
title
required
string
status
required
integer
>= 400 <= 599
detail
string
instance
string format: uri-reference
requestId
required
string
code
required
string
issues

The findings of a rejected IAM policy document (custom and resource policies).

Array<object>

One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.

object
code
required

The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.

string
statement
required

Index of the statement at fault; -1 for the document as a whole.

integer
>= -1
detail
required
string
action

The offending action, where one is at fault (ACTION_NOT_APPLICABLE).

string
errors

Field errors, for codes that carry them: each problem at its field (see FieldError). Documented on the responses that set it, e.g. approveNodeJoin’s INVALID_INPUT and JOIN_APPROVAL_REFUSED. Absent otherwise.

Array<object>

One field’s problem, the stage-2 installer API’s shape. field is the field’s path, message what is wrong with it.

object
field
required

The field’s path, e.g. links[0].interface, disks[1].confirm, mgmt.address or role; empty for the whole request.

string
message
required
string
details

Structured facts about the refusal, for codes that carry them. The shape is fixed per code and documented on the response that answers it, e.g. IMAGE_POOL_MISMATCH (see ImagePoolMismatchDetails) and IMAGE_IN_USE. Absent for codes that carry none.

object
key
additional properties
any

Example

{
"issues": [
{
"code": "ACTION_NOT_APPLICABLE",
"action": "compute:CreateVpc"
}
]
}
Retry-After
integer

Seconds to wait before retrying.