Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Documentation: glossary, FAQ, implementation guide, security guides
- Governance RFC workflow and RFC-0001 process
- Compliance docs: threat model and DPIA-lite baseline
- Lab-only federation handshake schema + RFC-0002

### Changed
- Clarified LoopSignal voting weight calculations
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ the repository documentation.
- Specification: `SPECIFICATION.md`
- API reference: `openapi.json`
- Security guide: `docs/security-guide.md`
- Federation handshake: `docs/federation-handshake.md`
- Threat model: `docs/compliance/threat-model.md`
- DPIA lite: `docs/compliance/dpia-lite.md`

Expand Down
32 changes: 32 additions & 0 deletions docs/federation-handshake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Federation Handshake (Lab Only)

This document defines a **lab-only** handshake payload used to introduce
two LOOP nodes in a controlled demo environment. It does **not** represent
production federation.

## Goals
- Exchange minimal node metadata.
- Confirm protocol version compatibility.
- Establish a lab-only trust acknowledgement.

## Handshake request
Schema: `schemas/handshake.schema.json` (`NodeHandshake`).

Required fields:
- `node_id` (e.g., `munich.loop`)
- `endpoint` (lab API URL)
- `capabilities` (string array)
- `timestamp` (ISO 8601)

## Handshake response
Schema: `schemas/handshake.schema.json` (`NodeHandshakeResponse`).

Required fields:
- `status` (`accepted` or `rejected`)
- `peer_id`
- `received_at`
- `lab_only: true`

## Security notes (lab stage)
- Request signatures are optional placeholders.
- Mutual TLS and request signing are planned for later TRL stages.
11 changes: 11 additions & 0 deletions examples/09-handshake-request.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"@context": "https://loop-protocol.org/v0.1.1",
"@type": "NodeHandshake",
"schema_version": "0.1.1",
"node_id": "munich.loop",
"name": "DEMO Munich Node",
"endpoint": "https://demo-munich.loop/api",
"capabilities": ["material-registry", "lab-relay"],
"timestamp": "2025-12-20T10:00:00Z",
"public_key": "-----BEGIN PUBLIC KEY-----MIIB...END PUBLIC KEY-----"
}
11 changes: 11 additions & 0 deletions examples/10-handshake-response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"@context": "https://loop-protocol.org/v0.1.1",
"@type": "NodeHandshakeResponse",
"schema_version": "0.1.1",
"status": "accepted",
"peer_id": "lab-hub.loop",
"capabilities": ["lab-relay"],
"received_at": "2025-12-20T10:00:05Z",
"lab_only": true,
"message": "Lab handshake accepted."
}
32 changes: 32 additions & 0 deletions rfcs/0002-federation-handshake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# RFC-0002: Federation Handshake (Lab Only)

## Summary
Introduce a minimal federation handshake payload for lab environments to
exchange node metadata and confirm protocol compatibility.

## Motivation
Multi-node demos require a clear, documented handshake to show how nodes
announce themselves without implying production readiness.

## Proposal
Add a `NodeHandshake` request and `NodeHandshakeResponse` schema (v0.1.1)
with a strict `lab_only: true` marker in responses.

## Security & Privacy
- Handshake signatures are optional placeholders.
- No PII is required.
- Production-grade mutual TLS and signing are deferred.

## Backwards Compatibility
No breaking changes; this is a new schema for lab-only use.

## Implementation Plan
1. Add handshake schema + examples.
2. Publish a lab-only handshake endpoint in the demo backend.
3. Document in the docs hub and governance index.

## Alternatives Considered
- Reuse NodeInfo schema (rejected: lacks handshake semantics).

## Open Questions
None for v0.1.
1 change: 1 addition & 0 deletions rfcs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ This directory contains LOOP Protocol Request for Comments (RFCs).

## Active
- RFC-0001: RFC process (v0.1)
- RFC-0002: Federation handshake (lab-only)

## How to submit
Use `rfcs/template.md` to create a new RFC and open a PR.
1 change: 1 addition & 0 deletions schemas/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ JSON Schema definitions for LOOP Protocol payloads.
- `offer.schema.json` (v0.1.1 minimal interop)
- `match.schema.json` (v0.1.1 minimal interop)
- `transfer.schema.json` (v0.1.1 minimal interop)
- `handshake.schema.json` (v0.1.1 lab federation)
- `loopcoin.schema.json`
- `loopsignal.schema.json`
- `transaction.schema.json`
Expand Down
134 changes: 134 additions & 0 deletions schemas/handshake.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://loop-protocol.org/schemas/v0.1.1/handshake.schema.json",
"title": "NodeHandshake",
"description": "Lab-only federation handshake payload for LOOP Protocol v0.1.1",
"oneOf": [
{ "$ref": "#/definitions/HandshakeRequest" },
{ "$ref": "#/definitions/HandshakeResponse" }
],
"definitions": {
"HandshakeRequest": {
"type": "object",
"required": [
"@context",
"@type",
"schema_version",
"node_id",
"name",
"endpoint",
"capabilities",
"timestamp"
],
"properties": {
"@context": {
"type": "string",
"const": "https://loop-protocol.org/v0.1.1"
},
"@type": {
"type": "string",
"const": "NodeHandshake"
},
"schema_version": {
"type": "string",
"const": "0.1.1"
},
"node_id": {
"type": "string",
"pattern": "^[a-z0-9\\-]+\\.loop$",
"examples": ["munich.loop"]
},
"name": {
"type": "string",
"minLength": 2,
"maxLength": 120,
"examples": ["DEMO Munich Node"]
},
"endpoint": {
"type": "string",
"format": "uri",
"pattern": "^https?://",
"examples": ["https://demo-munich.loop/api"]
},
"capabilities": {
"type": "array",
"minItems": 1,
"items": {
"type": "string"
},
"examples": [["material-registry", "lab-relay"]]
},
"public_key": {
"type": "string",
"description": "Optional public key for lab validation",
"examples": ["-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----"]
},
"timestamp": {
"type": "string",
"format": "date-time"
},
"signature": {
"type": "string",
"description": "Optional lab-only signature placeholder"
}
},
"additionalProperties": false
},
"HandshakeResponse": {
"type": "object",
"required": [
"@context",
"@type",
"schema_version",
"status",
"peer_id",
"capabilities",
"received_at",
"lab_only"
],
"properties": {
"@context": {
"type": "string",
"const": "https://loop-protocol.org/v0.1.1"
},
"@type": {
"type": "string",
"const": "NodeHandshakeResponse"
},
"schema_version": {
"type": "string",
"const": "0.1.1"
},
"status": {
"type": "string",
"enum": ["accepted", "rejected"]
},
"peer_id": {
"type": "string",
"pattern": "^[a-z0-9\\-]+\\.loop$",
"examples": ["lab-hub.loop"]
},
"capabilities": {
"type": "array",
"minItems": 1,
"items": {
"type": "string"
}
},
"received_at": {
"type": "string",
"format": "date-time"
},
"lab_only": {
"type": "boolean",
"const": true
},
"message": {
"type": "string",
"maxLength": 280
}
},
"additionalProperties": false
}
}
}