Peer Handshake v1¶
Source schema: doc/schemas/peer-handshake.v1.schema.json
Machine-readable schema for signed peer session establishment over the Node networking baseline. In v1 the signed surface is the deterministic CBOR image of the semantic handshake payload excluding only the signature field itself. Framing-only transport metadata may remain outside that signed payload. This contract remains node-scoped in the MVP baseline: it authenticates infrastructure and establishes an encrypted node-to-node session, while participant authentication happens later at the application-message layer over that established channel.
Governing Basis¶
doc/project/40-proposals/014-node-transport-and-discovery-mvp.mddoc/project/50-requirements/requirements-006.mddoc/project/60-solutions/node.md
Project Lineage¶
Requirements¶
Stories¶
Fields¶
| Field | Required | Shape | Description |
|---|---|---|---|
schema/v |
yes |
const: 1 |
Schema version. |
handshake/id |
yes |
string | Stable identifier of this handshake attempt. |
handshake/mode |
yes |
enum: hello, ack |
Explicit discriminator for the symmetric handshake family. In v1 both hello and ack remain artifacts of the same schema family, while ack/of-handshake-id provides the cryptographic response binding. |
ack/of-handshake-id |
no |
string | Reference to the original handshake when handshake/mode = ack. This MUST be part of the signed payload. |
ts |
yes |
string | Timestamp of the handshake artifact. |
sender/node-id |
yes |
string | Stable infrastructure identity of the Node sending this handshake artifact. In v1 this MUST use the canonical node:did:key:z... format, and it MUST NOT be replaced with participant-scoped identity material. |
recipient/node-id |
no |
string | Optional directed handshake recipient. If present, it is part of the signed payload. |
key/alg |
yes |
enum: ed25519 |
Algorithm of the sender key. |
key/public |
yes |
string | Canonical did:key fingerprint payload corresponding to sender/node-id. |
session/pub |
yes |
string | Fresh per-handshake X25519 public key encoded as raw unpadded base64url for the 32-byte public key. This field is ephemeral session material, not identity material, so it MUST NOT be wrapped as did:key or prefixed with multicodec bytes. |
protocol/version |
no |
string | Protocol version for interpreting this handshake family. In v1 this is primarily interpretation context and domain-separation input, not mutable handshake business data. |
transport/profile |
no |
enum: wss |
Framing-level or per-hop transport profile of the current session. This is not part of the signed semantic payload unless asserted as a capability claim. |
session/intent |
no |
enum: bootstrap, peer-connect, reconnect |
High-level intent of this session attempt. |
nonce |
yes |
string | Fresh nonce used to bind this session attempt and reduce replay risk. v1 replay protection assumes a roughly +-30s clock-skew window and per-peer nonce retention of about 120s. |
capabilities/offered |
no |
array | Optional capability claims offered as part of the signed handshake payload. |
terms/negotiated |
no |
object | Optional negotiated handshake terms carried inside the signed payload. |
signature |
yes |
ref: #/$defs/signature |
|
policy_annotations |
no |
object | Optional local or federation-local annotations that do not change core session semantics. |
Definitions¶
| Definition | Shape | Description |
|---|---|---|
signature |
object |
Conditional Rules¶
Rule 1¶
When:
{
"properties": {
"handshake/mode": {
"const": "ack"
}
},
"required": [
"handshake/mode"
]
}
Then:
{
"required": [
"ack/of-handshake-id"
]
}
Field Semantics¶
schema/v¶
- Required:
yes - Shape: const:
1
Schema version.
handshake/id¶
- Required:
yes - Shape: string
Stable identifier of this handshake attempt.
handshake/mode¶
- Required:
yes - Shape: enum:
hello,ack
Explicit discriminator for the symmetric handshake family. In v1 both hello and ack remain artifacts of the same schema family, while ack/of-handshake-id provides the cryptographic response binding.
ack/of-handshake-id¶
- Required:
no - Shape: string
Reference to the original handshake when handshake/mode = ack. This MUST be part of the signed payload.
ts¶
- Required:
yes - Shape: string
Timestamp of the handshake artifact.
sender/node-id¶
- Required:
yes - Shape: string
Stable infrastructure identity of the Node sending this handshake artifact. In v1 this MUST use the canonical node:did:key:z... format, and it MUST NOT be replaced with participant-scoped identity material.
recipient/node-id¶
- Required:
no - Shape: string
Optional directed handshake recipient. If present, it is part of the signed payload.
key/alg¶
- Required:
yes - Shape: enum:
ed25519
Algorithm of the sender key.
key/public¶
- Required:
yes - Shape: string
Canonical did:key fingerprint payload corresponding to sender/node-id.
session/pub¶
- Required:
yes - Shape: string
Fresh per-handshake X25519 public key encoded as raw unpadded base64url for the 32-byte public key. This field is ephemeral session material, not identity material, so it MUST NOT be wrapped as did:key or prefixed with multicodec bytes.
protocol/version¶
- Required:
no - Shape: string
Protocol version for interpreting this handshake family. In v1 this is primarily interpretation context and domain-separation input, not mutable handshake business data.
transport/profile¶
- Required:
no - Shape: enum:
wss
Framing-level or per-hop transport profile of the current session. This is not part of the signed semantic payload unless asserted as a capability claim.
session/intent¶
- Required:
no - Shape: enum:
bootstrap,peer-connect,reconnect
High-level intent of this session attempt.
nonce¶
- Required:
yes - Shape: string
Fresh nonce used to bind this session attempt and reduce replay risk. v1 replay protection assumes a roughly +-30s clock-skew window and per-peer nonce retention of about 120s.
capabilities/offered¶
- Required:
no - Shape: array
Optional capability claims offered as part of the signed handshake payload.
terms/negotiated¶
- Required:
no - Shape: object
Optional negotiated handshake terms carried inside the signed payload.
signature¶
- Required:
yes - Shape: ref:
#/$defs/signature
policy_annotations¶
- Required:
no - Shape: object
Optional local or federation-local annotations that do not change core session semantics.
Definition Semantics¶
$defs.signature¶
- Shape: object