@open-nodo/protocol
v0.3.0
Published
The Nodo wire contract: OpenAPI 3.1 + JSON Schemas (register, check-in, catalog, entitlements, aggregates) and the TypeScript types generated from them.
Readme
@open-nodo/protocol
The wire contract between Nodo instances and the rail. This package is the asset that gates the rail, the SDK, conformance, and any third-party reimplementation — change it first, regenerate, then change consumers.
- License: Apache-2.0 (we want this reimplemented in any language).
- Source of truth:
openapi/openapi.yaml(OpenAPI 3.1) plus the standaloneschemas/(JSON Schema 2020-12) for the persisted entities. - TypeScript types are generated, never hand-written:
npm run generate→src/generated/types.ts.
Use
npm run generate # OpenAPI -> src/generated/types.ts
npm run build # generate + tsc -> dist
npm run lint # redocly lint of the OpenAPI document
npm run mock # boot a Prism mock server from the specimport type { Instance, CheckinResponse } from "@open-nodo/protocol";
import { API_VERSION } from "@open-nodo/protocol";API surface (v1)
| Method & path | Auth | Purpose |
|---|---|---|
| POST /instances/register | registration token (body) | One-time: store the instance's Ed25519 public key → instance_id. |
| POST /instances/checkin | EdDSA-signed JWT | Identity + entitlements + latest versions + advisories. |
| GET /catalog/modules | none | Browse the catalog. |
| GET /catalog/modules/{key}/versions | none | Versions of a module. |
| GET /orgs/{orgId}/entitlements | session | What an org may run. |
| POST /selection-tokens | session | Mint the catalog→CLI handoff token. |
| POST /aggregates | EdDSA-signed JWT | Push a signed period rollup (Phase 4). |
| GET /groups/{groupId}/consolidation | session | Consolidated figures across a group (Phase 4). |
Check-in handshake (§C)
- Instance builds JWT claims
{ iss: instance_id, iat, jti }and signs with its Ed25519 private key (EdDSA). POST /instances/checkinwithAuthorization: Bearer <jwt>and body{ app_version, modules_running[] }.- Rail loads the instance by
iss, fetches the stored public key, verifies the signature, and rejects a seenjti(replay) or aniatoutside the freshness window. - Rail returns identity, entitlements,
latest_versions, and advisories. - Instance caches the response, enforces entitlements locally, and on rail-unreachable keeps the last-known entitlements for the offline-grace window.
Invariant: no shared secret is ever transmitted; the rail only ever stores public keys, and no raw financial/beneficiary data leaves the instance — only identity metadata and signed aggregates.
Entities
The seven persisted entities have authoritative standalone schemas in schemas/:
Module, ModuleVersion, Entitlement, Instance, Aggregate, Advisory, SelectionTokenClaims.
The OpenAPI document $refs them, so they are defined once. Versioning policy: VERSIONING.md.
