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.
- 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/v1anduril/lattice/entity/track/v1picogrid/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.
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:
| Prefix | Purpose |
|---|---|
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:
| Operation | Surface | Who is allowed |
|---|---|---|
| Read / subscribe any topic | Zenoh wire | Anyone with a jailbreak-CA-rooted leaf cert. |
Publish under <vendor>/** | Zenoh wire | Holder of the per-vendor cert (urn:goat-jb:vendor=<v> URI-SAN). |
| Register / edit a vendor | Portal API | Operator only. |
Register / edit a topic under <vendor>/... | Portal API | The vendor's portal API key, or operator. |
| Inspect / view any topic | Portal UI | Anyone 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.
| Format | When to pick |
|---|---|
json | Default for human-readable, structured data. Easy to debug. |
cbor | Compact binary; structured; common in IoT / sensor flows. |
msgpack | Compact binary; structured; popular in some ecosystems. |
protobuf:<MsgName> | High-performance binary. Producers should publish the .proto to attest/schema/.... |
text | Plaintext (logs, free-form events). UTF-8. |
raw | Opaque 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
- Operator mints the vendor from the home page. The portal returns a one-time API key + a downloadable bundle (cert + key + root + onboarding packet).
- Vendor receives the bundle out-of-band and the API key separately. They install the cert + key on whichever host publishes.
- Vendor declares topics — either via the Topics page UI, or programmatically via the API (see API Reference), or in bulk via YAML/JSON upload.
- Vendor publishes via the Zenoh CLI / SDK using the per-vendor cert. The router accepts writes under
<vendor>/**only. - 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.
?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.