Bridge Relay Configuration Reference
A bridge relay (Bondy Edge) connects one Bondy node, as a client, to a remote Bondy router, sharing a subset of procedures and topics between the two over a dedicated connection — distinct from cluster peer connections, which join nodes into the same cluster. Each bridge is named ($name) and configured independently; a node can run several bridges to several remote routers at once.
Enabling a bridge
Enables or disables the named bridge.
The host:port of the remote Bondy router's bridge relay listener (see Accepting bridges below for the listener side).
The transport for the connection to the remote router.
TLS
Client certificate for the bridge connection, when bridge.$name.transport = tls.
Client private key for the bridge connection.
CA certificate used to verify the remote router, when bridge.$name.tls.verify = verify_peer.
Whether the bridge verifies the remote router's certificate against bridge.$name.tls.cacertfile.
Whether hostname verification accepts a wildcard certificate matching bridge.$name.endpoint's host.
Comma-separated TLS protocol versions: 1.2, 1.3 or both.
Connection behaviour
Number of TCP connections to open to the remote router for this bridge.
How long to wait for the initial connection to the remote router before giving up.
Drops the connection once the bridge has been waiting this long for the local network to come back up, checked by counting the host's non-loopback IPv4 interfaces. Set to infinity to disable — useful for local development with no real network connection, where this check would otherwise fire spuriously.
Drops the connection once it has carried no message, in either direction, for this long. PING and PONG messages do not count. The bridge client logs "Shutting down client due to inactivity." with reason idle_timeout, and its supervisor starts a new client. Set to infinity to keep a silent connection open.
When this value is not longer than bridge.$name.ping.idle_timeout, the connection is dropped this long after it becomes idle, so ping.idle_timeout plus this value after the last message.
Controls when the bridge connection process hibernates to reclaim memory: idle hibernates after a period of inactivity, always after every message, never disables it.
The largest frame, in bytes, the bridge is meant to accept. The value is a positive integer or infinity. The default, 4194304 (4 MiB), matches the frame limits of Bondy's other carriers.
0 is rejected. Use infinity for no limit.
Not enforced in this release
Bondy validates and stores this value, but the bridge connection does not apply it. The connection reads length-prefixed frames with no size limit taken from this key.
Keepalive
Whether the edge probes a silent connection with PING control messages. This affects client (edge) initiated pings only; the remote router's pings are always answered regardless.
How long the connection may carry no message before it becomes idle. An idle connection is probed with PING when bridge.$name.ping is on. It is dropped at bridge.$name.idle_timeout, whether ping is on or off.
How long a probe waits for its answer before counting as a failed attempt.
How many unanswered probes mean a dead connection. After this many, the bridge client closes the connection and stops. Its supervisor then starts a new client, which dials again with a fresh retry budget. The supervisor restarts the client whether or not bridge.$name.reconnect is on.
Reconnection
Whether the bridge retries after a failed attempt, waiting the next backoff delay each time. A failed attempt is a connect error such as econnrefused, timeout or ehostunreach, a connection lost before a session opens, or a session the remote router refuses with an ABORT. The bridge retries an ABORT whatever its reason, such as a realm not yet provisioned on the remote router or a key it does not know, so the bridge connects once the remote router accepts it. Any other connect error stops the bridge. With off, the first failed attempt stops it. A stopped bridge reports stopped in bondy.router.bridge.status and stays stopped until bondy.router.bridge.start starts it again.
The retry budget: the number of failed attempts after which the bridge client exits. The budget has no time limit. Its supervisor then starts a new client, which dials again with a fresh budget.
These events count against the budget:
- A connection attempt that fails with
timeout,econnrefused,econnreset,ehostdown,enotconn,etimedout,enetdown,ehostunreachorenetunreach. Any other connect error stops the client at once. - A connection that is lost before a session opens on it.
When a connection that had an open session is lost, the client closes the socket and dials again at once, with a fresh budget. When the budget is spent, or when bridge.$name.reconnect is off, the client stops. Each bridge client is a permanent child of its supervisor, so the supervisor starts a new client with a new connection and a new budget. When its clients restart more than 20 times within 60 seconds, the supervisor itself stops, together with every bridge client on the node.
Backoff strategy between reconnection attempts: jitter randomises the delay to avoid many bridges reconnecting in lockstep, normal doesn't.
Initial (and minimum) delay between reconnection attempts.
Maximum delay between reconnection attempts, once backoff has grown.
Realm mapping
Each bridge shares one or more realms with the remote router; $id names one such mapping within the bridge.
The realm URI, matching on both this node and the remote router.
The identity the bridge authenticates as on the remote router for this realm, using cryptosign — see below for where the signing itself happens.
Delegated signing
The bridge never holds the realm's private key directly (except for local testing — see the warning below). Instead, signing a cryptosign challenge is delegated to one of:
The public key the remote router verifies the challenge signature against.
Not implemented. A bridge configured with this key fails to start. Use cryptosign.exec or cryptosign.privkey_env_var.
An external executable that performs the signing. Bondy runs it directly, never through a shell, with two arguments: the public key and the raw challenge bytes. It sends the program's standard output, unchanged, as the signature, and the remote router decodes that signature as hexadecimal, so the program has to print the hex-encoded Ed25519 signature and nothing else. The program has to answer within 10 seconds. Bondy also runs it once when the bridge starts, to check that it works.
Name of an environment variable holding the hex-encoded Ed25519 private key (the 32-byte seed). Bondy reads the variable when the bridge starts and signs with that key; the bridge fails to start if the variable is unset.
Testing only
Embeds the hex-encoded private key directly in bondy.conf. This exists for local testing only — use cryptosign.privkey_env_var or cryptosign.exec for anything else, so the private key never has to live in a configuration file.
Sharing procedures and topics
The value is a match spec: <uri> <match-type> <direction>, where <match-type> is exact, prefix, or wildcard, and <direction> is in, out (the default), or both.
Accepted but not enforced
Bondy validates this key, but the running bridge does not filter procedure sharing by it. The bridge proxies every local registration on the realm to the remote router, whatever this key says and whether or not it is set. Do not rely on it to keep a procedure off the remote router.
Shares a topic URI pattern between the two routers for this realm, using the same match-spec syntax as above. out subscribes locally and forwards matching events to the remote router, so remote subscribers can receive them; in would do the reverse (subscribing on the remote so local subscribers receive its events).
direction: in has no effect
Only out has an effect. The schema accepts in, and the in half of both, but the bridge logs a warning and does not subscribe on the remote router's side.
Forwarding guarantees
These two keys apply to every bridge on the node. They mirror the cluster's router.forward.* keys.
Meant to request acknowledged delivery for messages forwarded over bridges. Bondy accepts and stores this value, but no part of Bondy reads it in this release, so it has no effect.
Meant to control retransmission of unacknowledged bridge messages. Accepted and stored, not read: it has no effect in this release.
Accepting bridges
The other side of a bridge relay — the socket that accepts inbound connections from edge nodes bridging to this one — is an ordinary listener whose protocol is bridge_relay:
listeners.bridge.transport = tcp
listeners.bridge.protocol = bridge_relay
listeners.bridge.port = 18092The port is the one a bridging node points its own bridge.$name.endpoint at. All the listener-level settings apply — bind address, acceptor pool, connection limits, ping.*, TLS material for a tls transport — plus one key only this protocol reads: listeners.$name.auth_timeout, how long a connected peer router has to authenticate before the connection is dropped (5s if unset). A bridge-relay listener is not available over uds, and declaring services on one is an error — it serves one protocol by definition.
listeners.bridge_relay_tcp.* listeners.bridge_relay_tls.* The removed bridge.listener.{tcp,tls}.* keys are no longer read; a file still setting them starts no bridge-relay listener at all. See Migrating from the pre-1.0 keys.
See also
- Bridge Relay WAMP API Reference — add, remove, start, stop, and check the status of a bridge at runtime.
- Cluster Configuration Reference — the separate peer-plane connections that join nodes into one cluster.