ARCHITECTURE
Architecture
relay-pubsub owns protocol compatibility. Relay owns the durable event system. Here's how the boundary holds — and where relay-edge fits.
Get the highlights.
-
5Authenticated request steps from external caller to a scoped Relay identity
-
4Compatibility milestones already shipped — v0.1 through v0.4
-
2+Stateless gateway replicas recommended behind an HTTP/2-capable load balancer
-
v0.5Next milestone — multi-replica durable cursors move into Relay core
← Docs hub
relay-pubsub owns protocol compatibility. relay owns the durable event system.
+-------------------+ +--------------------+ +-------------------+
| Google SDK / REST | ---> | relay-pubsub | ---> | Zyvor Relay |
| | | | | |
| Publisher | | protocol adapter | | replicated log |
| Subscriber | | auth/tenant map | | cursors / ACK |
| StreamingPull | | error translation | | DLQ / replay |
+-------------------+ +--------------------+ +-------------------+
Take a closer look¶
RelayBackend prevents Google-specific request types from entering Relay core. The gRPC and REST adapters translate external API objects into TopicSpec, SubscriptionSpec, NewMessage and Delivery.
Implementations today:
--backend / RELAY_BACKEND |
Role |
|---|---|
memory |
Deterministic conformance / demos |
http |
Legacy invented Relay topics REST |
relay-events |
Production — Relay POST /v1/events + Action Gateway |
grpc |
Scaffold (src/grpc_backend.rs) — compiles; data plane returns "not fully implemented" until a Relay gRPC proto exists in-repo |
Prefer relay-events for production. The grpc stub keeps the trait boundary ready so a tonic Relay client can land without changing the Pub/Sub surface.
Compatibility gateways should be stateless. Run 2+ replicas behind an HTTP/2-capable load balancer. ACK IDs, cursors and exactly-once state must be durable in Relay, not process memory. The included memory backend is therefore only for tests/demos.
Each gateway process terminates its own TLS (gRPCS/HTTPS). In Kubernetes, mount a shared TLS secret or accept per-pod self-signed certs (current Helm default uses emptyDir — fine for single-replica lab stacks).
Local topic/subscription/action-queue state can be persisted to PUBSUB_DATA_DIR/state.json (PUBSUB_PERSIST=1, default on). That survives process restart on a single replica; multi-replica HA still requires sticky routing or durable state in Relay core.
relay-edge follows the same pattern: optional EDGE_TLS=1 with self-signed cert in internal/tlsutil, deployed alongside relay-pubsub via relay-edge deploy/scripts/deploy-k8s-remote.sh.
External Pub/Sub resource names contain projects/<project>, but that string is not authorization. Production flow:
- authenticate caller — static bearer (
RELAY_PUBSUB_AUTH_TOKEN) and/or OIDC JWT (PUBSUB_OIDC_JWKS_URL+ audience/issuer); - map identity to allowed projects (
PUBSUB_ALLOWED_PROJECTS,PUBSUB_IDENTITY_PROJECT_MAP); - authorize each resource operation against that allowlist;
- map the external Google-style project name to the internal Relay namespace;
- call Relay using a scoped service identity (
RELAY_AUTH_TOKEN).
mTLS / workload-identity passthrough can sit in front of the gateway; the gateway itself validates Bearer credentials today.
Integration stack¶
relay-edge (stamp + simulators)
│ HTTPS, topic = event type
▼
relay-pubsub (relay-events backend)
│ POST /v1/events
▼
Zyvor Relay (Accept → Act via POST /v1/actions → gateway)
See relay-edge Event matrix for the full cross-family test gate.
Compatibility roadmap¶
- ~~v0.1: core Publisher/Subscriber data path, REST, StreamingPull, time replay, DLQ~~
- ~~v0.2: official proto expansion, push dispatcher, snapshots, pagination, update APIs~~
- ~~v0.3: schema service, IAM compatibility subset, exactly-once + ordering + retry backoff, push dispatcher, admin inventory/logs, product console~~
- ~~v0.4: client conformance matrix (REST + Python/Node/Go), Helm console + PVC~~
- Unreleased (gateway): subscription attribute filters, topic schema enforcement, publish dedup, CloudEvents attribute projection — see FILTERS.md; native gRPC Relay backend scaffold (
RELAY_BACKEND=grpc) pending Relay proto - v0.5: multi-replica durable cursors in Relay core; broader official SDK TLS matrix
- Ongoing: durable ACK/cursors in Relay core (gateway persists local queue to disk today via
PUBSUB_DATA_DIR)