Master/Minion Protocol
This page describes the exact secure transport used between sysmaster and
sysminion.
It is intentionally lower-level than Secure Master/Minion Transport. Use this page when you need the precise wire shapes, handshake order, or rejection rules.
Frame Envelope
The outer wire format is length-prefixed:
write a big-endian
u32frame lengthwrite one JSON-encoded secure frame
Secure frame kinds are:
bootstrap_hellobootstrap_ackbootstrap_diagnosticdata
Handshake Binding
Every secure session is bound to:
minion id
minion RSA fingerprint
master RSA fingerprint
secure protocol version
connection id
client nonce
master nonce
That binding is carried in SecureSessionBinding and authenticated during
bootstrap.
Bootstrap Sequence
Normal secure session establishment is:
The minion opens a TCP connection to the master.
The minion sends
bootstrap_hello.The master validates: - the minion is registered - the stored RSA fingerprints match - at least one common secure transport version exists - the opening is not stale or replayed - there is no conflicting active session for that minion
The master replies with: -
bootstrap_ackon success, or -bootstrap_diagnosticon failureBoth sides derive the same short-lived session key from: - the authenticated Curve25519 shared secret - the completed binding - both ephemeral public keys
After that, every frame on that connection must be
data.
bootstrap_hello
Fields:
binding: initial session bindingsupported_versions: secure transport versions supported by the minionclient_ephemeral_pubkey: minion ephemeral Curve25519 public keybinding_signature: minion RSA signature over the authenticated openingkey_id: optional managed transport key id for reconnect/rotation continuity
Example:
{
"kind": "bootstrap_hello",
"binding": {
"minion_id": "minion-a",
"minion_rsa_fingerprint": "minion-fp",
"master_rsa_fingerprint": "master-fp",
"protocol_version": 1,
"connection_id": "conn-1",
"client_nonce": "client-nonce",
"master_nonce": "",
"timestamp": 1734739200
},
"supported_versions": [1],
"client_ephemeral_pubkey": "<base64>",
"binding_signature": "<base64>",
"key_id": "trk-current"
}
bootstrap_ack
Fields:
binding: completed binding with the master nonce filled insession_id: master-assigned secure session idkey_id: accepted transport key idrotation:none,rekey, orreregistermaster_ephemeral_pubkey: master ephemeral Curve25519 public keybinding_signature: master RSA signature over the authenticated ack
Example:
{
"kind": "bootstrap_ack",
"binding": {
"minion_id": "minion-a",
"minion_rsa_fingerprint": "minion-fp",
"master_rsa_fingerprint": "master-fp",
"protocol_version": 1,
"connection_id": "conn-1",
"client_nonce": "client-nonce",
"master_nonce": "master-nonce",
"timestamp": 1734739200
},
"session_id": "sid-1",
"key_id": "trk-current",
"rotation": "none",
"master_ephemeral_pubkey": "<base64>",
"binding_signature": "<base64>"
}
bootstrap_diagnostic
This is the only failure frame allowed before a secure session exists.
Fields:
code:unsupported_version,bootstrap_rejected,replay_rejected,rate_limited,malformed_frame, orduplicate_sessionmessage: human-readable rejection reasonfailure: retry/disconnect semantics
Example:
{
"kind": "bootstrap_diagnostic",
"code": "replay_rejected",
"message": "Secure bootstrap replay rejected for minion-a",
"failure": {
"retryable": false,
"disconnect": true,
"rate_limit": true
}
}
data
After bootstrap succeeds, all traffic uses data.
Fields:
protocol_version: negotiated secure transport versionsession_id: active secure session idkey_id: active managed transport key idcounter: per-direction monotonic counternonce: counter-derived libsodium noncepayload: authenticated encrypted payload
Example:
{
"kind": "data",
"protocol_version": 1,
"session_id": "sid-1",
"key_id": "trk-current",
"counter": 1,
"nonce": "<base64>",
"payload": "<base64>"
}
Enforcement Rules
The transport fails closed.
Important rules:
unsupported peers do not fall back silently
plaintext registration remains the only allowed non-secure setup path
plaintext
ehloand other normal minion traffic are rejectedduplicate secure sessions for the same minion are rejected
replayed bootstrap openings are rejected
replayed, duplicated, stale, or tampered
dataframes are rejectedreconnects create a new connection id, new nonces, and a fresh short-lived session key
Rotation Interaction
Managed transport rotation does not change the wire shape.
What changes during rotation:
the active
key_idcan changethe master may advertise rotation state in
bootstrap_ackreconnect after rotation establishes a fresh secure session using the new managed transport key id