commit 0cf87863d4cdb6b22b5a074c891d5f0cefa9ea62 Author: George Lambert Date: Tue Sep 15 22:17:17 2026 -0400 S05: NATS endpoint catalog, passthrough and error-bundle docs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3d43339 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build/ +__pycache__/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d1b6843 --- /dev/null +++ b/LICENSE @@ -0,0 +1,7 @@ +Copyright 2026 Verae / George Lambert + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files to use, copy, modify, +merge, publish, and distribute, subject to including this notice. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6bd301d --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +.PHONY: html latexpdf all +html: + $(SPHINXBUILD) -b html "$(SOURCEDIR)" "$(BUILDDIR)/html" +latexpdf: + $(SPHINXBUILD) -b latex "$(SOURCEDIR)" "$(BUILDDIR)/latex" + cd "$(BUILDDIR)/latex" && pdflatex -interaction=nonstopmode nats-service-endpoints.tex && pdflatex -interaction=nonstopmode nats-service-endpoints.tex +all: html latexpdf diff --git a/README.md b/README.md new file mode 100644 index 0000000..683b4a6 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# nats-service-endpoints + +Canonical list of NATS subjects for Verae / PFC / secure-messaging. + +* `catalog/endpoints.json` — secure-messaging + admin-config endpoints (full records) +* `catalog/pfc-derived.json` — imported from peergos-for-compliance `subjects.json` +* `catalog/schema.json` — JSON Schema for an endpoint row +* Docs: `source/` (Sphinx HTML + LaTeX PDF) + +Hub: https://git.georgelambert.org/marchon/system-git-sync + +Passthrough: the **destination** (and NATS subject) may be in the clear; the +**body** is ciphertext. The broker is untrusted. + +Not a HIPAA/SOC 2/ISO certificate. diff --git a/catalog/endpoints.json b/catalog/endpoints.json new file mode 100644 index 0000000..35eee72 --- /dev/null +++ b/catalog/endpoints.json @@ -0,0 +1,93 @@ +{ + "version": "1.0.0", + "broker": "untrusted", + "git": "https://git.georgelambert.org/marchon/nats-service-endpoints", + "related": [ + "https://git.georgelambert.org/marchon/secure-messaging", + "https://git.georgelambert.org/marchon/peergos-for-compliance", + "https://git.georgelambert.org/marchon/system-git-sync" + ], + "encryption_modes": { + "npe": "HPKE X25519-HKKE-SHA256-ChaCha20-Poly1305; dest inbox npe.inbox.", + "lab-xor": "pfc-lab-xor PSK; lab only", + "plain-lab": "JSON body; lab tests only", + "passthrough": "destination and NATS subject in the clear; payload ciphertext" + }, + "endpoints": [ + { + "name": "verae.sm.send", + "pattern": "core", + "for": "Deliver a passthrough secure message to a mailbox identity", + "from": ["console", "go-leaf", "access-api"], + "to": ["sm-leaf", "npe sidecar"], + "in": { + "header": ["to", "from_lookup_id", "alg", "error_token"], + "body": "ciphertext (not readable by broker or sender after send)" + }, + "out": {"ack": {"lookup_id": "string", "accepted": true}}, + "encryption": "passthrough-full-body", + "reject": ["missing to", "unsigned config", "alg not in signed config", "empty ciphertext when mode!=plain-lab"], + "dead": "verae.sm.dead" + }, + { + "name": "verae.sm.dead", + "pattern": "core", + "for": "Dead-letter failed service requests", + "from": ["sm-leaf"], + "to": ["error-handler"], + "in": {"header": ["error_code", "lookup_id", "to"], "body": "Network Error Bundle"}, + "out": "none", + "encryption": "system-key bundle plus sender-only status", + "reject": ["bundle missing ct_system"], + "dead": "none" + }, + { + "name": "verae.sm.error", + "pattern": "core", + "for": "Build and emit a Network Error Bundle", + "from": ["sm-leaf", "pfc-admin"], + "to": ["sender (ct_sender)", "system logger (ct_system)"], + "in": {"error_code": "string", "lookup_id": "string", "dest_class": "mailbox|service"}, + "out": {"ct_sender": "box to sender", "ct_system": "box to system public key"}, + "encryption": "no recipient payload; bounce metadata only", + "reject": ["unknown error_code"], + "dead": "verae.sm.log.summary" + }, + { + "name": "verae.sm.log.summary", + "pattern": "core", + "for": "Central log summaries of system failures (no message bodies)", + "from": ["sm-leaf", "pfc-admin"], + "to": ["central-log"], + "in": {"code": "string", "lookup_id": "string", "dest_class": "string"}, + "out": "ack", + "encryption": "summary plaintext allowed; never ciphertext of mail", + "reject": ["body-like fields present"], + "dead": "none" + }, + { + "name": "verae.admin.config.sign", + "pattern": "core", + "for": "Sign a new configuration payload; reject unsigned files at load", + "from": ["pfc-console", "pfc-config TUI"], + "to": ["admin-history cube"], + "in": {"payload": "object", "prev_signed": "object|null"}, + "out": "signed wrapper", + "encryption": "Ed25519 signature; payload may be lab-clear", + "reject": ["bad key_id", "canonical JSON mismatch"], + "dead": "verae.sm.dead" + }, + { + "name": "verae.admin.history.append", + "pattern": "core", + "for": "Append prev file, new file, and unified diff to DataCube admin-history", + "from": ["verae.admin.config.sign"], + "to": ["pfc CubeStore kind=admin-history"], + "in": {"prev": "string", "new": "string", "diff": "string", "actor": "string"}, + "out": "chain row", + "encryption": "chain hashes; not NPE (admin audit)", + "reject": ["empty actor"], + "dead": "none" + } + ] +} diff --git a/catalog/pfc-derived.json b/catalog/pfc-derived.json new file mode 100644 index 0000000..bbc3234 --- /dev/null +++ b/catalog/pfc-derived.json @@ -0,0 +1,1001 @@ +{ + "version": "0.2.1", + "endpoints": [ + { + "name": "verae.ts.request", + "pattern": "request-reply", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "verae-timestamp" + ], + "in": { + "fields": [ + "hash", + "cube_id", + "scope" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.ts.receipt", + "pattern": "pub", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "verae-timestamp" + ], + "in": { + "fields": [ + "receipt", + "merkle" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.ts.verify", + "pattern": "request-reply", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "verae-timestamp" + ], + "in": { + "fields": [ + "receipt_id" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.ts.held.query", + "pattern": "request-reply", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "verae-timestamp" + ], + "in": { + "fields": [ + "org_id" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.ts.batch", + "pattern": "request-reply", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "verae-timestamp" + ], + "in": { + "fields": [ + "items" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.hash.report", + "pattern": "request-reply", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "hashlog" + ], + "in": { + "fields": [ + "hash" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.storage.pin", + "pattern": "queue", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "pfc-ipfs" + ], + "in": { + "fields": [ + "cid", + "tier", + "cube_id", + "sha256", + "bytes_hex" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.storage.hydrate", + "pattern": "request-reply", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "pfc-ipfs" + ], + "in": { + "fields": [ + "cid", + "sha256" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.storage.replicate", + "pattern": "queue", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "pfc-repl" + ], + "in": { + "fields": [ + "sha256", + "bytes_hex", + "cube_id" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.pfc.replica.a.ingest", + "pattern": "request-reply", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "pfc-replica-a" + ], + "in": { + "fields": [ + "sha256", + "bytes_hex" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.pfc.replica.b.ingest", + "pattern": "request-reply", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "pfc-replica-b" + ], + "in": { + "fields": [ + "sha256", + "bytes_hex" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.cube.append", + "pattern": "queue", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "pfc-admin" + ], + "in": { + "fields": [ + "block", + "cube_id" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.cube.export", + "pattern": "queue", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "connector" + ], + "in": { + "fields": [ + "cube_id", + "format", + "share_mode" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.sig.verify", + "pattern": "request-reply", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "signatures" + ], + "in": { + "fields": [ + "object_sha256", + "signature_id" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.host.apps.start", + "pattern": "request-reply", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "supervisor" + ], + "in": { + "fields": [ + "app_id" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.host.apps.stop", + "pattern": "request-reply", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "supervisor" + ], + "in": { + "fields": [ + "app_id" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.host.apps.status", + "pattern": "request-reply", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "supervisor" + ], + "in": { + "fields": [ + "app_id" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.sample.job", + "pattern": "request-reply", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "desktop-host" + ], + "in": { + "fields": [ + "kind" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.app.manage", + "pattern": "request-reply", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "desktop-host" + ], + "in": { + "fields": [ + "op" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.compliance.session", + "pattern": "request-reply", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "pfc-admin" + ], + "in": { + "fields": [ + "op", + "cube_id", + "officers", + "session_id", + "sha256" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.inspect.open", + "pattern": "request-reply", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "pfc-admin" + ], + "in": { + "fields": [ + "cube_id", + "officers", + "purpose", + "scope", + "max_hours" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.inspect.access", + "pattern": "queue", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "pfc-admin" + ], + "in": { + "fields": [ + "cube_id", + "session_id", + "sha256", + "action" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.inspect.close", + "pattern": "request-reply", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "pfc-admin" + ], + "in": { + "fields": [ + "cube_id", + "session_id" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.inspect.revoke", + "pattern": "request-reply", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "pfc-admin" + ], + "in": { + "fields": [ + "cube_id", + "session_id" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.policy.attest", + "pattern": "queue", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "pfc-admin" + ], + "in": { + "fields": [ + "cube_id", + "org_pack" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.pfc.health", + "pattern": "request-reply", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "all-pfc" + ], + "in": { + "fields": [ + "service" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.pfc.cube.create", + "pattern": "request-reply", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "pfc-admin" + ], + "in": { + "fields": [ + "cube_id", + "profile" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.pfc.object.put", + "pattern": "request-reply", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "pfc-admin" + ], + "in": { + "fields": [ + "cube_id", + "text", + "hex" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.pfc.workspace.ensure", + "pattern": "request-reply", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "pfc-admin" + ], + "in": { + "fields": [ + "username" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.pfc.catalog.search", + "pattern": "request-reply", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "pfc-admin" + ], + "in": { + "fields": [ + "q", + "workspace_id" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.pfc.cube.copy", + "pattern": "request-reply", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "pfc-admin" + ], + "in": { + "fields": [ + "src", + "dest", + "sha256", + "stamp_scope", + "include_files" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.pfc.stamp.request", + "pattern": "request-reply", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "pfc-admin" + ], + "in": { + "fields": [ + "hash", + "created_ts", + "cube_id", + "stamp_scope" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.gossip.handshake", + "pattern": "pub", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "gossip" + ], + "in": { + "fields": [ + "from", + "to" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.gossip.envelope", + "pattern": "pub", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "gossip" + ], + "in": { + "fields": [ + "from" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.gossip.heartbeat", + "pattern": "pub", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "gossip" + ], + "in": { + "fields": [ + "node_id", + "ts_ms" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.gossip.receipt", + "pattern": "pub", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "gossip" + ], + "in": { + "fields": [ + "message_id", + "node_id", + "ok" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.gossip.peer.join", + "pattern": "pub", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "gossip" + ], + "in": { + "fields": [ + "addr", + "node_id" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + }, + { + "name": "verae.gossip.peer.leave", + "pattern": "pub", + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": [ + "pfc services", + "connectors" + ], + "to": [ + "gossip" + ], + "in": { + "fields": [ + "addr" + ] + }, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": [ + "unknown subject", + "missing required fields" + ], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance" + } + ] +} diff --git a/catalog/schema.json b/catalog/schema.json new file mode 100644 index 0000000..ebce849 --- /dev/null +++ b/catalog/schema.json @@ -0,0 +1,28 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "NATS-Service-Endpoints catalog", + "type": "object", + "required": ["version", "endpoints"], + "properties": { + "version": {"type": "string"}, + "endpoints": { + "type": "array", + "items": { + "type": "object", + "required": ["name", "for", "from", "to", "in", "out", "encryption", "reject"], + "properties": { + "name": {"type": "string"}, + "pattern": {"type": "string"}, + "for": {"type": "string"}, + "from": {"type": "array", "items": {"type": "string"}}, + "to": {"oneOf": [{"type": "string"}, {"type": "array", "items": {"type": "string"}}]}, + "in": {}, + "out": {}, + "encryption": {"type": "string"}, + "reject": {"type": "array", "items": {"type": "string"}}, + "dead": {"type": "string"} + } + } + } + } +} diff --git a/scripts/import_pfc_subjects.py b/scripts/import_pfc_subjects.py new file mode 100644 index 0000000..d59b6b3 --- /dev/null +++ b/scripts/import_pfc_subjects.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 +"""Merge peergos-for-compliance subjects.json into catalog/pfc-derived.json.""" + +from __future__ import annotations + +import json +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +PFC = Path("/Users/marchon/research/peergos-for-compliance/schemas/subjects.json") +OUT = ROOT / "catalog" / "pfc-derived.json" + + +def main() -> None: + src = json.loads(PFC.read_text()) + rows = [] + for s in src.get("subjects") or []: + rows.append( + { + "name": s["name"], + "pattern": s.get("pattern"), + "for": "PFC/Verae subject (see peergos-for-compliance/docs/nats-addresses.md)", + "from": ["pfc services", "connectors"], + "to": [s.get("owner") or "unknown"], + "in": {"fields": s.get("payload") or []}, + "out": "service-specific", + "encryption": "NATS envelope pfc-lab-xor or NPE sidecar; Pattern A apps never publish", + "reject": ["unknown subject", "missing required fields"], + "dead": "none", + "git": "https://git.georgelambert.org/marchon/peergos-for-compliance", + } + ) + OUT.write_text(json.dumps({"version": src.get("version"), "endpoints": rows}, indent=2) + "\n") + print("wrote", OUT, "n=", len(rows)) + + +if __name__ == "__main__": + main() diff --git a/source/conf.py b/source/conf.py new file mode 100644 index 0000000..ff03392 --- /dev/null +++ b/source/conf.py @@ -0,0 +1,10 @@ +project = "NATS Service Endpoints" +copyright = "2026, Verae" +author = "Verae / George Lambert" +extensions = [] +html_theme = "alabaster" +latex_engine = "pdflatex" +latex_documents = [ + ("index", "nats-service-endpoints.tex", "NATS Service Endpoints", "Verae", "manual"), +] +latex_elements = {"papersize": "letterpaper", "pointsize": "11pt"} diff --git a/source/config.rst b/source/config.rst new file mode 100644 index 0000000..5166f77 --- /dev/null +++ b/source/config.rst @@ -0,0 +1,18 @@ +Signed configuration +==================== + +A config file is unusable unless it is an Ed25519 wrapper:: + + { "payload": { ... }, "sig": { "alg": "ed25519", "key_id": "...", "signature": "hex" } } + +Select algorithms inside **payload** (the signed object): + +* ``crypto.mode``: ``npe`` | ``lab-xor`` | ``plain-lab`` +* ``routing.mode``: ``passthrough`` +* ``admin.history_cube``: cube id for admin-history +* ``crypto.system_key_id``: system public key id +* ``logging.mode``: ``summary`` + +After an admin console change: sign again, then append previous file, new +file, and unified diff to the admin-history DataCube +(``verae.admin.history.append``). diff --git a/source/endpoints.rst b/source/endpoints.rst new file mode 100644 index 0000000..b0488bb --- /dev/null +++ b/source/endpoints.rst @@ -0,0 +1,17 @@ +Endpoint records +================ + +Full JSON: ``catalog/endpoints.json``. PFC import: +``catalog/pfc-derived.json`` from +https://git.georgelambert.org/marchon/peergos-for-compliance/src/branch/main/schemas/subjects.json + +Secure-messaging subjects +------------------------- + +* ``verae.sm.send`` -- passthrough deliver; from console/leaf; reject unsigned + config and empty ciphertext (unless ``plain-lab``). +* ``verae.sm.dead`` -- dead letter; Network Error Bundle in body. +* ``verae.sm.error`` -- emit bundle: ``ct_sender`` + ``ct_system``. +* ``verae.sm.log.summary`` -- central summaries (codes, lookup_id, dest_class). +* ``verae.admin.config.sign`` -- Ed25519 wrap; unsigned files rejected. +* ``verae.admin.history.append`` -- prev, new, unified diff on DataCube chain. diff --git a/source/errors.rst b/source/errors.rst new file mode 100644 index 0000000..ee1a097 --- /dev/null +++ b/source/errors.rst @@ -0,0 +1,13 @@ +Errors and Network Error Bundle +================================ + +Never put the intended recipient payload in an error object. + +* **ct_sender** -- failure status encrypted so **only the sender** can read it. +* **ct_system** -- bounce report encrypted to the **system public key** for + logging/recovery (lookup_id, error_code, dest_class, respond flag). +* **Dead letter** -- ``verae.sm.dead`` with the same bundle. +* **Central log** -- ``verae.sm.log.summary``: codes only. + +The sender identifies the original message with ``lookup_id``, not by +decrypting what they sent. diff --git a/source/index.rst b/source/index.rst new file mode 100644 index 0000000..52bd8ae --- /dev/null +++ b/source/index.rst @@ -0,0 +1,29 @@ +NATS Service Endpoints +====================== + +Canonical catalog for Verae / PFC / secure-messaging on +https://git.georgelambert.org/marchon/nats-service-endpoints + +The NATS broker is **untrusted**. Production E2E is NPE (HPKE). Lab may use +``pfc-lab-xor``. This is **not** a HIPAA/SOC 2/ISO certificate. + +Related: `system-git-sync `_, +`secure-messaging `_, +`peergos-for-compliance `_. + +.. toctree:: + :maxdepth: 2 + + passthrough + endpoints + errors + config + tracing + +Passthrough +----------- + +Destination mailbox id and the NATS subject may be in the clear so routers +can work. The **body** is ciphertext. After send, the sender cannot open +that ciphertext; they keep a ``lookup_id`` only. The same rule applies to +the responder. diff --git a/source/passthrough.rst b/source/passthrough.rst new file mode 100644 index 0000000..5eff688 --- /dev/null +++ b/source/passthrough.rst @@ -0,0 +1,15 @@ +Passthrough routing +=================== + +:: + + sender --(ct, to, lookup_id)--> NATS subject + | | + | v + | sm-leaf / NPE + | | + +---- lookup_id only ---- v + recipient mailbox + +Header (clear): ``to``, ``from_lookup_id``, ``alg``, ``error_token``. +Body: ciphertext. Broker must not log ``ct``. diff --git a/source/tracing.rst b/source/tracing.rst new file mode 100644 index 0000000..2221ab0 --- /dev/null +++ b/source/tracing.rst @@ -0,0 +1,18 @@ +Message tracing +=============== + +Happy path:: + + 1. Load signed config (reject if unsigned). + 2. seal(body) -> envelope with to + ct + lookup_id. + 3. Publish verae.sm.send. + 4. Leaf acks {accepted:true, lookup_id}. + 5. Recipient opens ct with NPE (prod) or lab-xor (lab). + +Failure path:: + + 1. Leaf cannot deliver. + 2. Build Network Error Bundle (no mail body). + 3. Publish verae.sm.dead and verae.sm.error. + 4. Sender opens ct_sender; ops opens ct_system. + 5. Summary to verae.sm.log.summary.