One control plane for the fleet you actually have

Modern edge compute takes a native agent. Legacy black boxes get a palm-sized hardware gateway. Both surface through the same outbound-only tunnel, the same per-request authorization, the same audit trail — with zero inbound ports at any site, and no bastion, VPN, or jump host to operate.

  • Native agent for Linux edge compute you control — one static binary, no kernel module, no routing changes.
  • Hardware gateway for closed PLCs, broadcast gear, and unpatchable controllers that can't take an agent — the legacy device never touches the internet.
  • Same tunnel either way: outbound-only on 443/22, per-request auth, semantic audit. Works behind CGNAT, double NAT, and cellular.

How it works Read the security model

The problem — the fleet is not a monolith

Real fleets are a fragmented mess, and every remote-access vendor pretends otherwise. On one shelf: modern edge compute — a custom Yocto build, an NVR appliance, a gateway you have root on — where installing software is easy and buying hardware to reach it is absurd. On the next shelf: a fifteen-year-old HVAC controller with a web UI that stopped receiving patches during a previous American presidency, closed firmware, no shell, no writable filesystem — where installing software is impossible.

The market forces you to pick a side. Software-agent platforms cover the first shelf and shrug at the second. Rack-mounted hardware gateways cover the second at a price and footprint that make no sense for the first. So you end up running both — plus the VPN someone stood up in 2019 — and your "remote access strategy" is three access strategies with three audit trails.

RG Bridge collapses the dichotomy. It is one access model — device-initiated tunnel, per-request authorization, one audit trail — with two ways onto it, chosen per endpoint, not per fleet.

System architecture Two sites, one path out — same cluster Different left halves, an identical right half. Every device dials outbound only; nothing is ever exposed inbound.

How the Bridge works — two paths, one plane

Two on-ramps, chosen per endpoint. Everything above them is identical.

For Linux-based edge devices where you have root or vendor buy-in, the agent goes directly on the host: a single static Go binary — no kernel module, no routing-table edits, no DHCP, no firewall changes. It cannot strand the device's other services because it never acquires the privileges to.

  1. Key born on the device. First boot generates an ed25519 keypair on the device. The private key never leaves it; nothing is baked into your firmware image.
  2. Pairing is a human decision. A short-lived 6-character code, approved by an operator. The credentials handed back are signed by the one regional cluster the device paired with — worthless anywhere else.
  3. The device dials out. One long-lived OpenSSH connection — outbound, standard port — carrying one reverse forward per declared service: local HTTP, SSH, RTSP.
The account the tunnel lands on
AllowTcpForwarding remote    # may publish its own services upward
PermitOpen         none      # zero reach into the node's network
PermitTTY          no        # no shell, ever

Built as the inverse of a bastion account — it can publish its ports up, and do nothing else.

Your device's localhost ports become reachable — TLS-terminated, authorization-checked — through the cluster's nginx front, without one inbound port at your site.

For the closed PLC, the broadcast encoder, the industrial controller with no shell and no writable filesystem — the endpoints where "install our agent" is not an answer — RG ships the same bridge binary on a palm-sized, low-cost gateway instead. The physical layout is the security model.

  • Upstream path → your site WAN, or a dedicated LTE/5G backhaul.
  • Device path → a direct connection to the target, centimeters away.
  • Between them → your provisioning decision. The default is nothing.

Gated (default). The device gets no route to the internet at all. It keeps speaking whatever it has always spoken — an unauthenticated web UI, a raw TCP interface, Telnet-era protocols — but only to the gateway beside it, which translates that local interface into the same secure outbound tunnel the native agent uses.

Transparent (opt-in). For devices that legitimately need outbound access — vendor firmware updates, NTP, licensing — the gateway passes their traffic through instead. Inbound still doesn't exist: reachable-from-the-internet is never on the menu in either posture.

Both ways, the platform wraps access in the authentication, authorization, and audit the device itself never had. Practically: an operator opens the controller's ancient web UI in a browser, over TLS, gated by their role, logged with their name — while the controller remains as unreachable from the internet as it was the day it was unboxed.

One plane above both

From the cluster upward, the two tabs are indistinguishable.

  • Ports — allocated by the cluster, never chosen by the endpoint.
  • Firewall — only the SSH range is open at the node. Every HTTP/RTSP service is firewall-closed and served exclusively through nginx, with a full authorization check on the way in.
  • Control — pull-based. A 60-second HTTPS heartbeat, outside the tunnel, answered with at most one pending command; an endpoint that was offline simply collects its work on the next poll.
  • Operator auth — never to the endpoint. Opening a console mints a short-lived (1-hour) token, audience-bound to that one cluster, roles resolved at mint time. The browser talks directly to the cluster; the cluster verifies the token offline and re-runs RBAC on every request.

A custom Yocto build and an unpatchable HVAC controller produce the same audit rows: actor, verb, target. That is the abstraction being sold — not a tool, an access layer that normalizes a fragmented fleet into one security model.

When the primary WAN dies, the control plane doesn't

With an optional LTE module, the hardware gateway becomes genuine out-of-band infrastructure — not "OOB" as a marketing synonym for remote access, but a control path that survives the failure of the network it manages.

Failover is a provisioning decision, not a factory default: you switch it on when you configure the gateway for cellular backhaul, and it ships off. Enabled, it is engineered rather than hoped for. Carrier-loss detection on the uplink is a configured interval — roughly two seconds as provisioned, versus the seventy-five a keepalive timeout would need to notice — and the bridge re-establishes its outbound tunnel over the cellular path by binding egress at the socket level, per connection. No routing-table rewrite, no OS-level failover daemon, and its health probes verify reachability of your cluster, not merely "some internet." When the primary WAN returns, it walks back.

That puts a site's worth of legacy equipment behind dedicated cellular resilience at a footprint of one palm-sized box — a category that traditionally means rack-mounted enterprise failover appliances with their own management overhead. And because the tunnel is outbound-only on ports every cellular carrier permits, it works on the CGNAT connectivity that cellular actually gives you, with no static IP and no carrier negotiation.

vs. a bastion host

A bastion is the right answer when you own the network and the endpoints are static: one hardened, exposed SSH box in front of infrastructure that trusts it. We know — we run one ourselves, for our own cluster nodes, which are static servers on infrastructure we control. That's the honest dividing line: bastion where you own the network and endpoints don't move; device-initiated tunnel where you don't and they do.

For a mixed fleet, the bastion model breaks three ways:

Exposure. A bastion is a permanently internet-facing SSH endpoint whose compromise is a pivot into everything behind it. RG's cluster node has an SSH port too — but the accounts endpoints land on can't open a shell, can't local-forward, can't reach anything. The blast radius of the exposed port is "someone can publish a port," not "someone is inside."

Reachability. A bastion still has to reach the endpoint. Behind customer NAT that means a port forward or a second hop inside a network you don't administer. And it assumes the endpoint speaks SSH at all — your Yocto box does; the HVAC controller with only a web UI does not, so the bastion model was never even applicable to half your fleet. Both RG paths dial out; there is nothing to reach, and the gateway path covers endpoints SSH-based access could never touch.

Credentials and audit. Bastion access means operator SSH keys or an SSH CA lifecycled across hosts, and a bastion logs sessions — who connected, when, to where. What happened inside requires separate recording, and anything tunnelled through -L is opaque. RG distributes zero operator keys to endpoints — operators never authenticate to the endpoint at all — and audit is semantic: pairing approvals, port allocations, token issuance, revocations, each with actor and target.

vs. a VPN

A VPN makes an endpoint a member of a network, and then you spend the rest of the project constraining what membership means: ACLs, segmentation, routing policy — network-layer trust decided once at connect time, hoped correct forever. That's a questionable model for edge compute you control. For a legacy controller with known-unpatchable CVEs in its web stack, putting it on an overlay is the opposite of containment.

Trust shape. A compromised VPN peer is on the network, lateral movement bounded only by ACLs. A compromised RG endpoint holds one key that can publish ports on one cluster and one token scoped to its own identity — no lateral reach exists to constrain. The legacy device behind a hardware gateway holds nothing: it was never enrolled in anything.

Provisioning. A VPN peer needs a config — key, endpoint, allowed IPs — provisioned before first connection: pre-shared material, extractable and painful to rotate across a deployed fleet. RG's native agent generates its key on the device under human-approved pairing; nothing leaks from a factory image. And a VPN client is not even installable on the closed-firmware shelf, which is where the gateway path exists.

Footprint. A VPN needs a kernel module or daemon plus routing changes — on device classes that are frequently BusyBox with a read-only filesystem. The native agent is one static binary that changes no routes. The gateway asks the legacy device for nothing at all.

Audit. A VPN logs connections and flows; it cannot tell you a user changed an encoder's bitrate — that's invisible below L7. RG's unit of audit is the API call.

Where a VPN is genuinely the right tool, we use one: cluster nodes mesh over WireGuard — full mesh, no central relay, adding a node is an identity operation rather than a firewall change. The point is not that VPNs are bad; it's that overlay membership is the wrong primitive for endpoints sitting in networks you don't control — and an impossible one for endpoints that can't run a client.

vs. a jump host

A jump host is a bastion by another name, so the section above applies — plus the failure mode chaining adds: every hop is another box that must be up, patched, and reachable, and another place identity degrades into "whoever holds the key to the next machine." By the second hop, your audit trail is a guess. For legacy gear the chain gets grimmer still: the last hop is typically a Windows box on the OT network running a vendor tool, which is now your de facto access infrastructure.

With RG there is no hop to chain. The operator's browser connects directly to the cluster over TLS with a token carrying their actual identity and roles; the cluster reaches the endpoint's service at loopback over the endpoint's own outbound tunnel — whether that tunnel originates from a native agent or from the gateway one cable away from a thirty-year-old controller. One authenticated boundary, one audit point, no intermediate shell anywhere.

The comparison table

Dimension Bastion / jump host VPN RG Bridge
Modern edge compute (agent-capable) Reachable only via port-forward or hop Client install + routing changes Native agent: one static binary, outbound-only
Legacy / closed-firmware gear Not applicable without extra machinery Client not installable Hardware gateway; device stays offline
Inbound exposure at site Port forward or second hop required Reachable concentrator; UDP egress often blocked None — outbound 443/22/53 only
Works behind CGNAT / cellular No Sometimes, with relays Yes, by construction
WAN-failure resilience Dead with the site network Dead with the site network Opt-in LTE on gateway; ~2 s detection when enabled
Trust model Network position + shell Overlay membership + ACLs Per-request authorization
Pre-shared material on endpoint Operator keys / SSH CA Peer config provisioned pre-deploy None — key generated on device; legacy device holds nothing
Compromised endpoint yields Pivot behind the bastion Lateral reach bounded by ACLs Port-publishing on one cluster; no reach
Unit of audit Session Connection / flow API call, with actor and verb
Offboarding Remove keys everywhere; live sessions unaffected Revoke peer config; wait out sessions Next token mint (≤1 h); per-request RBAC

What a compromise actually gets you

A compromised native-agent endpoint yields: one ed25519 key usable only to open reverse forwards on one cluster, under an account with no shell and no local forwarding, plus one token scoped to that endpoint's identity and checked on every call. No lateral network reach.

A compromised hardware gateway yields the same — the gateway is architecturally just another endpoint running the same binary under the same locked-down account. What it additionally touches is the one legacy device on its isolated port; what it cannot do is turn that into internet exposure for the device, because the device has no route out except through the tunnel the platform authorizes per request.

A compromised cluster node yields the CA certificate — the verify half. The signing half never leaves the cloud; a node can check operator tokens but cannot mint them, and a token minted for one cluster is unreplayable at another: wrong audience and wrong key.

A lost or stolen gateway gives its new holder a login screen, not a login. The local management GUI is protected by a per-device password generated by the cluster at pairing — the factory default password works only before pairing, no admin:admin, and nothing printed on a sticker to peel off. The password is held by the platform, revealed only to operators authenticated to that device's own cluster with the role to see it, and the reveal itself is written to the audit trail with the actor's name. If a gateway goes missing, rotation is a single click in the console — the new password is delivered on the device's next check-in, and the old one dies with it.

A demoted operator keeps a valid token for at most its remaining lifetime — up to one hour — after which the next mint resolves their new (or absent) role. Admins can revoke a live token immediately at the cluster.

Where the trade-offs live

  • Latency of control, not of data. Commands arrive on the next heartbeat, not sub-second. If you need millisecond push control, this is the wrong shape.
  • The complexity moved into the agent — deliberately. A VPN's routing layer gives interface failover for free; we built it at the socket level instead, precisely so the agent never touches the OS's routes. An agent you can read beats a routing table you can't, but it's a choice, not magic.
  • A gateway is one more physical thing — powered, cabled, occasionally replaced. For agent-capable endpoints, use Path A; the hardware exists for the shelf where software was never an option.
  • A cluster is a dependency for humans. Endpoints keep running and stay reachable if the cloud is down — clusters are autonomous at runtime — but operator consoles need a token from the cloud within the hour, unless on the cluster-local login path.

FAQ

Q: Is this "just reverse SSH"?

The transport is deliberately boring — one OpenSSH process, one reverse forward per service, inspectable with ps on your own hardware. What the platform adds is everything a raw reverse tunnel lacks. Below the tunnel: on-device key generation with human-approved pairing, cluster-allocated ports under a forwarding-only account, firewall exposure classes. Above it: your device's plain-HTTP GUI becomes a real HTTPS URL in the operator's browser — the cluster fronts it with TLS, a per-request permission check, and WebSocket support for live interfaces — with offline-verifiable operator tokens, per-request RBAC, and one audit trail across both deployment paths. Roll your own reverse SSH and you've solved reachability; the certificate, the authorization gate in front of that admin panel, and the answer to "who touched this device in March" are still your problem. Boring transport, opinionated everything-else.

Q: Native agent or hardware gateway — how do I choose?

Per endpoint, not per fleet. Root (or vendor buy-in) on a Linux-based device → native agent, no hardware. Closed firmware, no shell, no writable filesystem, or a protocol stack you'd rather never expose → gateway. Mixed sites run both against the same cluster with the same permissions model.

Q: Does the legacy device behind a gateway get an internet connection?

That's your call — the gateway supports both postures, and isolation is the default.

Gated (default): the device talks only to the gateway on its direct link. The agent's bridge mode does exactly three things — assign the LAN address, bring the link up, check the target answers — and deliberately nothing else: no IP forwarding, no NAT, no DHCP, no routing-table changes. With nothing forwarding its packets, the device has no path to the internet and no credentials of its own to lose; it is reachable through the authorized tunnel and through nothing else.

Transparent (opt-in): for devices that legitimately need outbound access — firmware updates from the vendor, NTP, a licensing server — the gateway can be provisioned as a NAT router at the OS level. Kernel forwarding plus masquerade on the uplink, applied at provisioning and persistent across reboots, with one manual step on the device itself: point its default gateway and DNS at the gateway's LAN address. The device then reaches out through the gateway's uplink while remaining unreachable from the internet — outbound-only cuts both ways.

The two postures don't blur: pass-through is host-level configuration, deliberately kept out of the agent, so enabling internet for the device never widens what the tunnel exposes — inbound access still exists only as the authorized, audited forwards the platform allocated.

Q: Why not WireGuard or Tailscale on the endpoint?

Both — WireGuard raw, or managed beautifully by Tailscale — end at the same primitive: the endpoint becomes a peer on an overlay network, and you then govern what membership means with ACLs. Tailscale genuinely fixes VPN operations (enrollment, NAT traversal, key rotation); it doesn't change the trust shape. A peer has network reach to constrain; an RG endpoint has none to begin with — it publishes N declared services through an outbound tunnel and every action against them is authorized per request and logged as a verb, not a flow. Membership is also simply unavailable on the closed-firmware shelf: you can't install a daemon on a device with no shell — which is what the hardware gateway exists for, and the legacy device behind it is enrolled in nothing at all. Where peering is the right model — our own cluster nodes, infrastructure one party controls — we run WireGuard ourselves.

Q: Does traffic go through your cloud?

Endpoint traffic terminates at the regional cluster; the operator's browser connects to the cluster directly. The cloud mints identity and manages the fleet — it is not a data-path relay.

Your fleet is not a monolith, and your access model shouldn't require pretending it is. Deploy the agent where you can, drop the gateway where you can't, and get one thing either way: an infrastructure layer where nothing is reachable, everything is authorized per request, and a Yocto build and a legacy controller leave the same audit trail.

Vendor platform requirements