Trial Docs

Overview

The Zenoh Trial is a shared Zenoh fabric where vendors publish small messages under their own namespace and any consumer on the fabric can subscribe to them. The trial is deliberately relaxed compared to production: anyone can read everything; vendors can only publish under their own prefix; schemas are declared as a polite convention rather than enforced at the router.

Three pages, three jobs.
  • Home — who is registered.
  • Topics — what each vendor says they publish (key pattern, format, schema reference).
  • Inspector — what is actually flowing right now.

Namespace convention

Every Zenoh key on the trial fabric matches this shape:

<vendor>/<system>/<producer-discretion-arbitrary-depth>/v<N>

Examples that pattern in real life:

  • homemade-sensors/garage/temperature/v1
  • anduril/lattice/entity/track/v1
  • picogrid/ecn/observation/aggregate/v2

The operator owns <vendor>. An operator-registered prefix grants the holder the right to publish anywhere under <vendor>/**. Once past the vendor prefix, the structure is entirely the vendor's choice — there is no operator-imposed taxonomy for what <system> means or how deep the key can go.

Why the version suffix matters. v1, v2, etc. are part of the key, not metadata. A breaking change to a message means publishing to a new key (.../v2) — not changing the wire shape on the existing key. Subscribers consume the version they were built for.

Reserved prefixes

Two prefixes are operator-only, regardless of vendor registration:

PrefixPurpose
system/**Operator broadcasts (notices, fleet announcements, sunset banners). Vendors cannot publish here.
attest/schema/**Schema declarations per topic pattern (see Schemas + formats). Vendor-published; visible to all readers.

ACL contract

Two layers govern who can do what:

OperationSurfaceWho is allowed
Read / subscribe any topicZenoh wireAnyone with a jailbreak-CA-rooted leaf cert.
Publish under <vendor>/**Zenoh wireHolder of the per-vendor cert (urn:goat-jb:vendor=<v> URI-SAN).
Register / edit a vendorPortal APIOperator only.
Register / edit a topic under <vendor>/...Portal APIThe vendor's portal API key, or operator.
Inspect / view any topicPortal UIAnyone on the fabric.

The portal API key authenticates to the portal only (vendor self-service +metadata editing). The per-vendor X.509 leaf cert is the Zenoh-wire credential — the router keys off the cert's URI-SAN to allow writes only under that vendor's namespace.

Schemas + formats

Each topic declares a format; the inspector dispatches decode by that string.

FormatWhen to pick
jsonDefault for human-readable, structured data. Easy to debug.
cborCompact binary; structured; common in IoT / sensor flows.
msgpackCompact binary; structured; popular in some ecosystems.
protobuf:<MsgName>High-performance binary. Producers should publish the .proto to attest/schema/....
textPlaintext (logs, free-form events). UTF-8.
rawOpaque bytes. Inspector renders hex only.

Schema reference convention. When the format requires an out-of-band schema (Protobuf especially), the producer publishes the schema source to attest/schema/<vendor>/<system>/.../v<N> — the same key path as the data topic, prefixed with attest/schema/. The inspector fetches the schema at decode time.

A dedicated Schemas page (artifact upload + browse) is the next slice of work after this docs page lands. Until then, vendors publish schema content directly to attest/schema/... via the Zenoh CLI or SDK.

Versioning

  • Additive changes (new optional fields, new metadata): keep the same version key, document the change in the topic description.
  • Breaking changes (removed fields, changed semantics, type changes): publish to a new v<N+1> key. The portal surfaces sibling versions in the inspector so you can spot stale subscribers.
  • Deprecation: retire the old topic in the portal (DELETE /api/vendors/{v}/topics/{id}). The row stays in the registry for audit; the inspector hides it by default.

Onboarding flow

  1. Operator mints the vendor from the home page. The portal returns a one-time API key + a downloadable bundle (cert + key + root + onboarding packet).
  2. Vendor receives the bundle out-of-band and the API key separately. They install the cert + key on whichever host publishes.
  3. Vendor declares topics — either via the Topics page UI, or programmatically via the API (see API Reference), or in bulk via YAML/JSON upload.
  4. Vendor publishes via the Zenoh CLI / SDK using the per-vendor cert. The router accepts writes under <vendor>/** only.
  5. Anyone on the fabric can subscribe + inspect.

Bulk topic editing

Per-vendor topic sets can be downloaded as a single YAML or JSON file (GET /api/vendors/{v}/topics/export) and re-uploaded after editing (POST /api/vendors/{v}/topics/import). The Topics page has download and upload buttons that drive these endpoints.

The wire format (YAML):

vendor: homemade-sensors
topics:
  - key_pattern: homemade-sensors/garage/temperature/v1
    format: json
    schema_ref: attest/schema/homemade-sensors/garage/temperature/v1
    description: "Garage thermometer — DHT22 over ESP32, 30s cadence."
    publish_to_storage: false
  - key_pattern: homemade-sensors/garage/door-state/v1
    format: json
    schema_ref: attest/schema/homemade-sensors/garage/door-state/v1
    description: "Reed-switch door open/closed events."
    publish_to_storage: false

Import semantics. Upsert by (vendor, key_pattern). Topics already in the registry that aren't in the file are left alone (additive mode, default). Pass ?mode=replace to also retire (soft-delete) topics absent from the file. Pass ?dry_run=true to see the computed diff without applying.

Recommended workflow for bigger edits: download the current file, edit offline, run an import with ?dry_run=true to preview the diff, then re-run without dry-run to apply.

API

Full machine-readable OpenAPI 3.1 spec at /openapi.yaml; interactive UI at API Reference. Every operation accepts a Authorization: Bearer <key> header — operator key for the full surface, per-vendor key for vendor-scoped routes.

Two quick-curl examples:

# list vendors
curl -H "Authorization: Bearer $PORTAL_API_KEY" \
     https://portal.jb.netbird.datalandingzone.net/api/vendors | jq .

# export topics for homemade-sensors as YAML
curl -H "Authorization: Bearer $PORTAL_API_KEY" \
     "https://portal.jb.netbird.datalandingzone.net/api/vendors/homemade-sensors/topics/export?format=yaml"

Troubleshooting

I registered a topic but can't publish

Two layers to check: (1) topic is in the portal registry (visible on the Topics page); (2) the router's ACL has been reloaded. The portal writes the ACL JSON5 file on every vendor mint, but in v1 the operator must run docker exec zenoh-router kill -HUP 1 manually to reload. After that, the per-vendor cert's URI-SAN gives you write access under your prefix.

The inspector renders my bytes as hex

Your topic's format is raw (default) or the inspector can't decode the declared format. Pick a richer format in the topic row's edit action.

My API key stopped working

Vendor keys are bcrypt-hashed at registration; if you lost yours, the operator must mint a new vendor entry. The cert keeps working independent of the portal key.