Skip to main content

Gateway Relay & Cloudflare Tunnel

Connected gateways can run on machines behind NAT, firewalls, VPNs, or corporate networks. The gateway relay is a built-in reverse tunnel that lets these gateways receive inbound API traffic without opening any inbound ports. For production deployments that need a dedicated hostname or edge features, you can use Cloudflare Tunnel instead.

How the relay works

When a connected gateway starts, it derives a dedicated relay hostname from KEEPTRUSTS_API_URL and opens a persistent outbound WebSocket connection:

KEEPTRUSTS_API_URL=https://api.eu.keeptrusts.com
↓ automatic derivation
Gateway ──WSS──▶ wss://relay.eu.keeptrusts.com/v1/gateway/relay

The relay hostname is region-aware: the api. prefix in the API URL is replaced with relay. automatically. For example:

API URLDerived relay URL
https://api.eu.keeptrusts.comwss://relay.eu.keeptrusts.com/v1/gateway/relay
https://api.us.keeptrusts.comwss://relay.us.keeptrusts.com/v1/gateway/relay

You do not need to configure the relay URL — it is derived automatically from the API URL.

  1. The gateway authenticates using its machine token (KEEPTRUSTS_API_TOKEN).
  2. It sends a registration message containing its runtime_registration_id.
  3. The control plane acknowledges and begins dispatching inbound API requests through the WebSocket.
  4. The relay client forwards each request to the local gateway HTTP server and sends the response back.
  5. Streaming responses (including SSE for LLM completions) are forwarded through the same channel.

If the WebSocket connection drops, the gateway reconnects automatically with exponential backoff (1 second initial delay, 30 second maximum).

Configuration

The relay is enabled by default for all connected gateways. No additional configuration is required — the gateway derives the relay endpoint automatically from KEEPTRUSTS_API_URL and uses the same environment variables you already set during installation:

VariablePurpose
KEEPTRUSTS_API_URLControl-plane URL — the relay hostname is derived from this automatically
KEEPTRUSTS_API_TOKENMachine token used to authenticate the WebSocket
KEEPTRUSTS_RUNTIME_REGISTRATION_IDGateway identity sent during registration

The local gateway HTTP server listens on port 41002 by default. The relay client forwards dispatched requests to http://127.0.0.1:<gateway-port> with a 30-second per-request timeout.

Using Cloudflare Tunnel with gateways

For production deployments where you need a dedicated hostname, edge caching, enterprise compliance, or custom domain routing, use Cloudflare Tunnel to expose the gateway.

1. Install cloudflared

# macOS
brew install cloudflared

# Debian / Ubuntu
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg \
| sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" \
| sudo tee /etc/apt/sources.list.d/cloudflared.list
sudo apt-get update && sudo apt-get install -y cloudflared

2. Create a tunnel

cloudflared tunnel login
cloudflared tunnel create keeptrusts-gateway

3. Configure the tunnel

Create ~/.cloudflared/config.yml to route traffic to the local gateway:

tunnel: keeptrusts-gateway
credentials-file: /home/<user>/.cloudflared/<tunnel-id>.json

ingress:
- hostname: gateway.example.com
service: http://localhost:41002
- service: http_status:404

4. Set up DNS

cloudflared tunnel route dns keeptrusts-gateway gateway.example.com

This creates a CNAME record pointing gateway.example.com to the tunnel.

5. Start the tunnel

cloudflared tunnel run keeptrusts-gateway

For persistent operation, install cloudflared as a system service:

sudo cloudflared service install

6. Register the hostname with Keeptrusts

Update the gateway record so the platform knows its public address:

kt gateway update --name production --public-url https://gateway.example.com

Or set the public URL in the console Gateways page.

When to prefer Cloudflare Tunnel over the built-in relay

ConsiderationBuilt-in relayCloudflare Tunnel
Setup complexityNone — works out of the boxRequires cloudflared install and DNS
Dedicated hostnameNot applicableCustom domain (e.g. gateway.example.com)
Edge featuresNot applicableDDoS protection, caching, access policies
ComplianceTraffic routes through Keeptrusts relayTraffic routes through your Cloudflare account
Latency overhead~10–50 ms relay hopTypically lower — direct edge-to-origin

Both approaches can coexist. The built-in relay provides zero-config connectivity, while Cloudflare Tunnel gives you full control over the network path.

Monitoring

Console

The Gateways page in the console shows each gateway's relay connection status and last-seen timestamp.

CLI

kt gateway status --name production

The output includes relay connection state and the last heartbeat time.

Heartbeats

The control plane sends periodic WebSocket pings. If the gateway stops responding to pings, the platform marks it as disconnected. Reconnection happens automatically on the gateway side.

Troubleshooting

"relay connection failed"

  • Verify KEEPTRUSTS_API_URL is set and the host is reachable.
  • Confirm the firewall allows outbound HTTPS and WSS traffic on port 443.
  • Check DNS resolution for both the API host and the derived relay host (e.g. relay.eu.keeptrusts.com).

"authentication failed"

  • The machine token may be expired or revoked. Rotate it in the console or via kt auth token create.
  • Verify KEEPTRUSTS_API_TOKEN matches the token assigned to this gateway.

High latency through the relay

The built-in relay adds approximately 10–50 ms of overhead per request. If latency is critical:

  • Use Cloudflare Tunnel for a shorter network path.
  • Place the gateway closer to the API consumers.
  • Use direct connectivity if the network allows inbound traffic.

Gateway reconnects frequently

  • Unstable network connections cause repeated backoff cycles. Check the host's network stability.
  • If the gateway logs show the backoff reaching 30 seconds, the control plane may be temporarily unavailable — the gateway will recover automatically.

Next steps