Skip to main content

RPC Gateway Pattern

Do not expose raw node RPC ports directly to untrusted clients. Put a gateway layer between callers and node processes so authentication, TLS, rate limits, request shaping, logging, and method policy are applied consistently.

internet / partner network
|
v
+-------------------------+
| TLS load balancer |
| - certificate rotation |
| - HTTP/2 or WebSocket |
+-------------------------+
|
v
+-------------------------+
| API gateway / proxy |
| - API key or JWT auth |
| - token bucket limits |
| - CORS origin policy |
| - method allowlist |
| - request size limits |
+-------------------------+
|
v
+-------------------------+
| private node pool |
| - read RPC nodes |
| - WS subscription nodes |
| - submit nodes |
+-------------------------+
|
v
+-------------------------+
| internal-only services |
| - admin RPC |
| - metrics |
| - consensus/engine APIs |
+-------------------------+
LayerResponsibilityCommon implementation
TLS terminationPublic certificates, protocol negotiation, cipher policyCloud load balancer, nginx, Envoy
Auth proxyAPI key validation, JWT validation, partner allowlistsEnvoy external auth, nginx auth_request, API gateway plugin
Rate limiterPer-key, per-IP, method, and connection budgetsEnvoy rate limit service, Redis token bucket
Method policyAllow public read methods; block admin/debug methodsGateway route rules or JSON-RPC method filter
Upstream poolSeparate read, write, WebSocket, and internal nodesKubernetes services, service mesh, DNS pools

:::warning Exposure boundary Gateway controls reduce risk, but they do not make unsafe methods safe. Keep admin namespaces, Ethereum Engine API, Beacon API internals, metrics, and validator management ports off public routes. :::

Minimal nginx-style shape

server {
listen 443 ssl http2;
server_name rpc.example.org;

client_max_body_size 1m;

location / {
auth_request /_auth;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Request-Id $request_id;
proxy_read_timeout 30s;
proxy_pass http://private-rpc-pool;
}

location /ws {
auth_request /_auth;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
proxy_pass http://private-ws-pool;
}
}

Use /developer/rate-limiting, /developer/cors-origin-policy, and /developer/websocket-scaling to size the gateway policy.