Skip to content

Add TCP and TLS listening support to the cardano-rpc gRPC server - #1322

Merged
carbolymer merged 4 commits into
masterfrom
mgalazyn/feature/rpc-enable-http
Sep 3, 2026
Merged

Add TCP and TLS listening support to the cardano-rpc gRPC server#1322
carbolymer merged 4 commits into
masterfrom
mgalazyn/feature/rpc-enable-http

Conversation

@carbolymer

@carbolymer carbolymer commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

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:

  • a unix domain socket (existing behaviour, still the default), or
  • HTTP/2 without TLS (h2c) on a configured IP address and port, or
  • HTTP/2 over TLS on a configured IP address and port, with certificate, private key and optional chain certificate files.

The bind address defaults to 127.0.0.1 and 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's rpcSocketPath field is replaced by rpcEndpoint, of a new RpcEndpoint sum type:

data RpcEndpoint
  = RpcEndpointUnixSocket !SocketPath
  | RpcEndpointHttp !IP !PortNumber
  | RpcEndpointHttps !IP !PortNumber !RpcTlsFiles

RpcTlsFiles is a new record of File-typed certificate and key paths. RpcEndpoint has a Pretty instance, and TraceRpc gained a TraceRpcServerListening constructor, 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-port binds to 127.0.0.1 unless 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, when SSLKEYLOGFILE is 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 http2 apply. 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 upstream grapesy feature).

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 SSLKEYLOGFILE is set in its environment.

Checklist

  • Commit sequence broadly makes sense and commits have useful messages
  • New tests are added if needed and existing tests are updated. See Running tests for more details
  • Self-reviewed the diff
  • Changelog fragment added in .changes/

@carbolymer carbolymer self-assigned this Aug 28, 2026
@carbolymer carbolymer moved this to In Progress in DevTools roadmap Aug 28, 2026
@carbolymer
carbolymer force-pushed the mgalazyn/feature/rpc-enable-http branch 2 times, most recently from 590e4ae to 919a74d Compare August 28, 2026 16:25
@carbolymer
carbolymer marked this pull request as ready for review August 28, 2026 16:26
Copilot AI lite review requested due to automatic review settings August 28, 2026 16:26
@carbolymer carbolymer changed the title gRPC: Add HTTP endpoint support Add TCP and TLS listening support to the cardano-rpc gRPC server Aug 28, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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-only rpcSocketPath with rpcEndpoint :: RpcEndpoint (unix socket / h2c / h2 + TLS) and add TLS credential types.
  • Update server startup to translate RpcEndpoint into the underlying grapesy ServerConfig, 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 as breaking.

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.

Comment thread .changes/20260828_cardano_rpc_grpc_tcp_listener.yml Outdated
Comment thread cardano-rpc/src/Cardano/Rpc/Server/Config.hs Outdated
Comment thread cardano-rpc/src/Cardano/Rpc/Server/Internal/Tracing.hs Outdated
@carbolymer
carbolymer force-pushed the mgalazyn/feature/rpc-enable-http branch 2 times, most recently from 9ffcc0d to 999ef20 Compare August 28, 2026 16:36
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
carbolymer force-pushed the mgalazyn/feature/rpc-enable-http branch from 7873fbe to 6799515 Compare August 31, 2026 15:40
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.
@carbolymer
carbolymer enabled auto-merge September 3, 2026 09:05
@carbolymer
carbolymer added this pull request to the merge queue Sep 3, 2026
Merged via the queue into master with commit 304fe00 Sep 3, 2026
31 of 33 checks passed
@carbolymer
carbolymer deleted the mgalazyn/feature/rpc-enable-http branch September 3, 2026 09:33
@github-project-automation github-project-automation Bot moved this from In Progress to Done in DevTools roadmap Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants