Add TCP and TLS listening support to the cardano-rpc gRPC server - #1322
Merged
Conversation
carbolymer
force-pushed
the
mgalazyn/feature/rpc-enable-http
branch
2 times, most recently
from
August 28, 2026 16:25
590e4ae to
919a74d
Compare
carbolymer
marked this pull request as ready for review
August 28, 2026 16:26
carbolymer
requested review from
CarlosLopezDeLara,
Jimbo4350,
disassembler,
erikd and
palas
as code owners
August 28, 2026 16:26
Contributor
There was a problem hiding this comment.
Pull request overview
This PR extends cardano-rpc’s server configuration to support listening on HTTP/2 endpoints (h2c and TLS) in addition to the existing unix-domain socket listener, and wires that into server startup and tracing. It introduces a breaking API change in the exposed Cardano.Rpc.Server.Config module by replacing rpcSocketPath with a new rpcEndpoint sum type.
Changes:
- Replace
RpcConfigF’s unix-socket-onlyrpcSocketPathwithrpcEndpoint :: RpcEndpoint(unix socket / h2c / h2 + TLS) and add TLS credential types. - Update server startup to translate
RpcEndpointinto the underlyinggrapesyServerConfig, and emit a new lifecycle trace when starting. - Add dependencies needed for IP/port representation (
iproute,network) and add a changelog fragment marking the change asbreaking.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| cardano-rpc/src/Cardano/Rpc/Server/Internal/Tracing.hs | Adds a new TraceRpc constructor and pretty-printing for server start/listen events. |
| cardano-rpc/src/Cardano/Rpc/Server/Config.hs | Introduces RpcEndpoint/TLS types and replaces rpcSocketPath with rpcEndpoint in the exposed config. |
| cardano-rpc/src/Cardano/Rpc/Server.hs | Maps RpcEndpoint to ServerConfig (unix/h2c/h2+TLS) and emits the new trace event on startup. |
| cardano-rpc/cardano-rpc.cabal | Adds iproute and network dependencies required by the new endpoint types. |
| .changes/20260828_cardano_rpc_grpc_tcp_listener.yml | Adds a changelog fragment describing the new endpoint support and marking it as breaking. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
9 tasks
carbolymer
force-pushed
the
mgalazyn/feature/rpc-enable-http
branch
2 times, most recently
from
August 28, 2026 16:36
9ffcc0d to
999ef20
Compare
Replace the rpcSocketPath field of RpcConfigF with an RpcEndpoint sum type: the server listens either on a unix domain socket (default, rpc.sock next to the node socket) or on plaintext TCP (HTTP/2 without TLS) when a listen port is configured. The TCP listen address defaults to 127.0.0.1. Trace the resolved endpoint on server start.
Add an RpcEndpointTcpTls endpoint: when TLS certificate and private key files are configured, the server listens with TLS on the configured host and port. Grapesy's default of honouring the SSLKEYLOGFILE environment variable is explicitly disabled so the node never silently logs TLS session keys.
Build the gRPC server with mkGrpcServer and runServer instead of the runServerWithHandlers convenience wrapper, so the HTTP/2 settings are explicit at the call site. Halve the maximum concurrent streams per connection to 64; all other settings keep grapesy defaults, including the HTTP/2 flood-protection rate limits and flow-control windows.
carbolymer
force-pushed
the
mgalazyn/feature/rpc-enable-http
branch
from
August 31, 2026 15:40
7873fbe to
6799515
Compare
Redact handler exceptions sent to clients: the response carries the error message only, never call stacks or internal detail; full detail is still traced server-side. Bound script evaluation requests by a 64 KiB pre-decode size cap, the protocol maximum transaction size and a limit of 100 redeemers. Limit UTxO reads to 20000 keys and block fetches to 500 references per request. Document the security posture in the package README.
Jimbo4350
approved these changes
Sep 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
The cardano-rpc gRPC server has only listened on a unix domain socket, so any remote or non-local access needed a proxy such as Envoy in front of it (the stance in ADR-018). This PR adds native HTTP/2 listeners.
The server can now listen on one of:
The bind address defaults to
127.0.0.1and accepts an IPv4 or IPv6 literal. Configuring both a socket path and a listen port is rejected at configuration parse time. The node configuration surface (RpcListenAddress/RpcListenPort/RpcTls*keys and the matching--grpc-listen-*/--grpc-tls-*CLI flags) lives in cardano-node; this PR is the cardano-rpc library support.Node-side configuration: IntersectMBO/cardano-node#6668.
Breaking change
RpcConfigF'srpcSocketPathfield is replaced byrpcEndpoint, of a newRpcEndpointsum type:RpcTlsFilesis a new record ofFile-typed certificate and key paths.RpcEndpointhas aPrettyinstance, andTraceRpcgained aTraceRpcServerListeningconstructor, emitted when the server starts, reporting the active endpoint.Security considerations
The RPC server has no authentication or authorisation. Every method is open to anyone who can reach the listener, including transaction submission and script evaluation. Everything it serves is public chain data, so the concern is resource consumption and node exposure rather than confidentiality.
The defaults are conservative. The server stays off unless you pass
--grpc-enable, it listens on a unix socket by default, and--grpc-listen-portbinds to127.0.0.1unless you name another address. The node warns at startup when RPC is enabled on a block producer, when the listener binds a non-loopback address, whenSSLKEYLOGFILEis set with TLS active, and when the TLS private key is group- or world-readable.TLS (
--grpc-tls-certificate,--grpc-tls-private-key) encrypts the connection and lets a client verify the node. It does not restrict who may call, and there is no client certificate support. A TLS listener on a public address is as open as a cleartext one.Concurrent streams are capped at 64 per connection, and the HTTP/2 flood limits and flow-control windows from
http2apply. Error responses carry only a redacted message, never call stacks or internal detail; full detail stays in the node's traces. Script evaluation is bounded: a 64 KiB pre-decode cap, the protocol's max transaction size, and at most 100 redeemers. UTxO reads are capped at 20000 keys, and block fetches at 500 references per request. Not bounded: the number of concurrent connections, idle connections (never reaped), and the total gRPC message size (a per-message limit needs an upstreamgrapesyfeature).Keep the listener on loopback or a trusted network segment. Anywhere else, put a reverse proxy in front of it to terminate TLS and handle authentication and rate limiting, as ADR-018 describes. Note that the server writes TLS key log material if
SSLKEYLOGFILEis set in its environment.Checklist
.changes/