Skip to content

Commit 579e14d

Browse files
authored
feat(federation): add handshake schema and RFC (#4)
1 parent 6ee2ab8 commit 579e14d

File tree

9 files changed

+224
-0
lines changed

9 files changed

+224
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717
- Documentation: glossary, FAQ, implementation guide, security guides
1818
- Governance RFC workflow and RFC-0001 process
1919
- Compliance docs: threat model and DPIA-lite baseline
20+
- Lab-only federation handshake schema + RFC-0002
2021

2122
### Changed
2223
- Clarified LoopSignal voting weight calculations

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ the repository documentation.
9696
- Specification: `SPECIFICATION.md`
9797
- API reference: `openapi.json`
9898
- Security guide: `docs/security-guide.md`
99+
- Federation handshake: `docs/federation-handshake.md`
99100
- Threat model: `docs/compliance/threat-model.md`
100101
- DPIA lite: `docs/compliance/dpia-lite.md`
101102

docs/federation-handshake.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Federation Handshake (Lab Only)
2+
3+
This document defines a **lab-only** handshake payload used to introduce
4+
two LOOP nodes in a controlled demo environment. It does **not** represent
5+
production federation.
6+
7+
## Goals
8+
- Exchange minimal node metadata.
9+
- Confirm protocol version compatibility.
10+
- Establish a lab-only trust acknowledgement.
11+
12+
## Handshake request
13+
Schema: `schemas/handshake.schema.json` (`NodeHandshake`).
14+
15+
Required fields:
16+
- `node_id` (e.g., `munich.loop`)
17+
- `endpoint` (lab API URL)
18+
- `capabilities` (string array)
19+
- `timestamp` (ISO 8601)
20+
21+
## Handshake response
22+
Schema: `schemas/handshake.schema.json` (`NodeHandshakeResponse`).
23+
24+
Required fields:
25+
- `status` (`accepted` or `rejected`)
26+
- `peer_id`
27+
- `received_at`
28+
- `lab_only: true`
29+
30+
## Security notes (lab stage)
31+
- Request signatures are optional placeholders.
32+
- Mutual TLS and request signing are planned for later TRL stages.

examples/09-handshake-request.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"@context": "https://loop-protocol.org/v0.1.1",
3+
"@type": "NodeHandshake",
4+
"schema_version": "0.1.1",
5+
"node_id": "munich.loop",
6+
"name": "DEMO Munich Node",
7+
"endpoint": "https://demo-munich.loop/api",
8+
"capabilities": ["material-registry", "lab-relay"],
9+
"timestamp": "2025-12-20T10:00:00Z",
10+
"public_key": "-----BEGIN PUBLIC KEY-----MIIB...END PUBLIC KEY-----"
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"@context": "https://loop-protocol.org/v0.1.1",
3+
"@type": "NodeHandshakeResponse",
4+
"schema_version": "0.1.1",
5+
"status": "accepted",
6+
"peer_id": "lab-hub.loop",
7+
"capabilities": ["lab-relay"],
8+
"received_at": "2025-12-20T10:00:05Z",
9+
"lab_only": true,
10+
"message": "Lab handshake accepted."
11+
}

rfcs/0002-federation-handshake.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# RFC-0002: Federation Handshake (Lab Only)
2+
3+
## Summary
4+
Introduce a minimal federation handshake payload for lab environments to
5+
exchange node metadata and confirm protocol compatibility.
6+
7+
## Motivation
8+
Multi-node demos require a clear, documented handshake to show how nodes
9+
announce themselves without implying production readiness.
10+
11+
## Proposal
12+
Add a `NodeHandshake` request and `NodeHandshakeResponse` schema (v0.1.1)
13+
with a strict `lab_only: true` marker in responses.
14+
15+
## Security & Privacy
16+
- Handshake signatures are optional placeholders.
17+
- No PII is required.
18+
- Production-grade mutual TLS and signing are deferred.
19+
20+
## Backwards Compatibility
21+
No breaking changes; this is a new schema for lab-only use.
22+
23+
## Implementation Plan
24+
1. Add handshake schema + examples.
25+
2. Publish a lab-only handshake endpoint in the demo backend.
26+
3. Document in the docs hub and governance index.
27+
28+
## Alternatives Considered
29+
- Reuse NodeInfo schema (rejected: lacks handshake semantics).
30+
31+
## Open Questions
32+
None for v0.1.

rfcs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ This directory contains LOOP Protocol Request for Comments (RFCs).
44

55
## Active
66
- RFC-0001: RFC process (v0.1)
7+
- RFC-0002: Federation handshake (lab-only)
78

89
## How to submit
910
Use `rfcs/template.md` to create a new RFC and open a PR.

schemas/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ JSON Schema definitions for LOOP Protocol payloads.
77
- `offer.schema.json` (v0.1.1 minimal interop)
88
- `match.schema.json` (v0.1.1 minimal interop)
99
- `transfer.schema.json` (v0.1.1 minimal interop)
10+
- `handshake.schema.json` (v0.1.1 lab federation)
1011
- `loopcoin.schema.json`
1112
- `loopsignal.schema.json`
1213
- `transaction.schema.json`

schemas/handshake.schema.json

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"$id": "https://loop-protocol.org/schemas/v0.1.1/handshake.schema.json",
4+
"title": "NodeHandshake",
5+
"description": "Lab-only federation handshake payload for LOOP Protocol v0.1.1",
6+
"oneOf": [
7+
{ "$ref": "#/definitions/HandshakeRequest" },
8+
{ "$ref": "#/definitions/HandshakeResponse" }
9+
],
10+
"definitions": {
11+
"HandshakeRequest": {
12+
"type": "object",
13+
"required": [
14+
"@context",
15+
"@type",
16+
"schema_version",
17+
"node_id",
18+
"name",
19+
"endpoint",
20+
"capabilities",
21+
"timestamp"
22+
],
23+
"properties": {
24+
"@context": {
25+
"type": "string",
26+
"const": "https://loop-protocol.org/v0.1.1"
27+
},
28+
"@type": {
29+
"type": "string",
30+
"const": "NodeHandshake"
31+
},
32+
"schema_version": {
33+
"type": "string",
34+
"const": "0.1.1"
35+
},
36+
"node_id": {
37+
"type": "string",
38+
"pattern": "^[a-z0-9\\-]+\\.loop$",
39+
"examples": ["munich.loop"]
40+
},
41+
"name": {
42+
"type": "string",
43+
"minLength": 2,
44+
"maxLength": 120,
45+
"examples": ["DEMO Munich Node"]
46+
},
47+
"endpoint": {
48+
"type": "string",
49+
"format": "uri",
50+
"pattern": "^https?://",
51+
"examples": ["https://demo-munich.loop/api"]
52+
},
53+
"capabilities": {
54+
"type": "array",
55+
"minItems": 1,
56+
"items": {
57+
"type": "string"
58+
},
59+
"examples": [["material-registry", "lab-relay"]]
60+
},
61+
"public_key": {
62+
"type": "string",
63+
"description": "Optional public key for lab validation",
64+
"examples": ["-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----"]
65+
},
66+
"timestamp": {
67+
"type": "string",
68+
"format": "date-time"
69+
},
70+
"signature": {
71+
"type": "string",
72+
"description": "Optional lab-only signature placeholder"
73+
}
74+
},
75+
"additionalProperties": false
76+
},
77+
"HandshakeResponse": {
78+
"type": "object",
79+
"required": [
80+
"@context",
81+
"@type",
82+
"schema_version",
83+
"status",
84+
"peer_id",
85+
"capabilities",
86+
"received_at",
87+
"lab_only"
88+
],
89+
"properties": {
90+
"@context": {
91+
"type": "string",
92+
"const": "https://loop-protocol.org/v0.1.1"
93+
},
94+
"@type": {
95+
"type": "string",
96+
"const": "NodeHandshakeResponse"
97+
},
98+
"schema_version": {
99+
"type": "string",
100+
"const": "0.1.1"
101+
},
102+
"status": {
103+
"type": "string",
104+
"enum": ["accepted", "rejected"]
105+
},
106+
"peer_id": {
107+
"type": "string",
108+
"pattern": "^[a-z0-9\\-]+\\.loop$",
109+
"examples": ["lab-hub.loop"]
110+
},
111+
"capabilities": {
112+
"type": "array",
113+
"minItems": 1,
114+
"items": {
115+
"type": "string"
116+
}
117+
},
118+
"received_at": {
119+
"type": "string",
120+
"format": "date-time"
121+
},
122+
"lab_only": {
123+
"type": "boolean",
124+
"const": true
125+
},
126+
"message": {
127+
"type": "string",
128+
"maxLength": 280
129+
}
130+
},
131+
"additionalProperties": false
132+
}
133+
}
134+
}

0 commit comments

Comments
 (0)