Start the proof of a join code (join listener only).
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).
Request Bodyrequired
Section titled “Request Bodyrequired”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
The code’s first two characters, which pick the code.
Example
4FThe OPAQUE KE1 message, base64.
Responses
Section titled “Responses”The listener’s answer.
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
Names the exchange in the proof. Valid for 2 minutes, once.
The OPAQUE KE2 message, base64.
The cluster root CA’s SHA-256 (DER), as hex pairs.
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.
object
The findings of a rejected IAM policy document (custom and resource policies).
One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.
object
The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.
Index of the statement at fault; -1 for the document as a whole.
The offending action, where one is at fault (ACTION_NOT_APPLICABLE).
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.
One field’s problem, the stage-2 installer API’s shape.
field is the field’s path, message what is wrong with it.
object
The field’s path, e.g. links[0].interface, disks[1].confirm,
mgmt.address or role; empty for the whole request.
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
Example
{ "issues": [ { "code": "ACTION_NOT_APPLICABLE", "action": "compute:CreateVpc" } ]}Missing or invalid token.
object
The findings of a rejected IAM policy document (custom and resource policies).
One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.
object
The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.
Index of the statement at fault; -1 for the document as a whole.
The offending action, where one is at fault (ACTION_NOT_APPLICABLE).
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.
One field’s problem, the stage-2 installer API’s shape.
field is the field’s path, message what is wrong with it.
object
The field’s path, e.g. links[0].interface, disks[1].confirm,
mgmt.address or role; empty for the whole request.
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
Example
{ "issues": [ { "code": "ACTION_NOT_APPLICABLE", "action": "compute:CreateVpc" } ]}Headers
Section titled “Headers”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.
object
The findings of a rejected IAM policy document (custom and resource policies).
One finding of a rejected IAM policy document. A rejection lists every finding, so the author fixes the document in one round trip.
object
The finding, e.g. INVALID_DOCUMENT, UNKNOWN_ACTION, ACTION_NOT_APPLICABLE.
Index of the statement at fault; -1 for the document as a whole.
The offending action, where one is at fault (ACTION_NOT_APPLICABLE).
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.
One field’s problem, the stage-2 installer API’s shape.
field is the field’s path, message what is wrong with it.
object
The field’s path, e.g. links[0].interface, disks[1].confirm,
mgmt.address or role; empty for the whole request.
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
Example
{ "issues": [ { "code": "ACTION_NOT_APPLICABLE", "action": "compute:CreateVpc" } ]}Headers
Section titled “Headers”Seconds to wait before retrying.
