Skip to content

feat(preconf): add TLS support to sequencer server and validator client#3115

Open
fridrik01 wants to merge 3 commits into
preconf-devfrom
tls-preconf-server-hardening
Open

feat(preconf): add TLS support to sequencer server and validator client#3115
fridrik01 wants to merge 3 commits into
preconf-devfrom
tls-preconf-server-hardening

Conversation

@fridrik01
Copy link
Copy Markdown
Contributor

@fridrik01 fridrik01 commented May 28, 2026

The preconf sequencer and validators exchange JWT auth tokens and execution payloads over plain HTTP. For a sequencer reachable over the public internet, this leaks credentials and MEV-sensitive transaction ordering in cleartext. This PR adds opt-in TLS to the sequencer server and validator client along with the tooling to run and rotate it.

More specifically, the main changes are:

Server TLS (beacon/preconf/server.go)

  • tls-cert-path + tls-key-path switch the API to HTTPS, served via ServeTLS with a GetCertificate hook.
  • The TCP listener binds synchronously in Start(), so a bad cert/key or an in-use port fails node startup loudly instead of being logged in a goroutine behind a dead endpoint.
  • No dual-mode listener: when TLS is configured the server only speaks HTTPS.

Client pinning (beacon/preconf/client.go)

  • Optional sequencer-ca-cert-path pins the sequencer to a single CA and rejects certificates from any other CA, guarding against CA mis-issuance and BGP-hijack attacks. When unset, it falls back to the system trust store.
  • A TLS 1.2 floor is enforced on every connection.

Config and operations

  • Config.Validate() rejects half-configured TLS (cert without key, or pinning without an https:// URL).
  • The node logs a startup warning when a validator points at a plaintext sequencer on a non-loopback host.
  • The sequencer hot-reloads its certificate on SIGHUP (next to the existing whitelist reload), so rotation needs no restart and a bad cert file leaves the old one serving.
  • New CLI flags and config.toml template entries cover all three paths.

Devnet (kurtosis/)

  • The kurtosis preconf devnet now runs with TLS enabled by default (preconf.tls: true). At plan time it generates an internal CA and a CA-signed server cert (SAN matching the sequencer service name), serves the leaf on the sequencer, and pins the CA on the validators. This mirrors the production trust topology rather than a self-signed shortcut. TLS stays a toggle, so the devnet can still run plaintext with tls: false.

Documentation (beacon/preconf/README.md)

  • Documents the preconf system and the full TLS workflow: cert generation for dev and production, pinning, and rotation.

Test plan

  • Unit tests cover certificate pinning (correct CA connects, wrong CA rejected), plaintext rejection, SIGHUP cert reload, bind-failure handling, and config validation.
  • Verified end to end on the kurtosis preconf devnet (via make start-devnet-preconf). Confirmed validators fetch payloads from the sequencer over HTTPS with CA pinning and no certificate verification failures.

@fridrik01 fridrik01 self-assigned this May 28, 2026
@fridrik01 fridrik01 force-pushed the tls-preconf-server-hardening branch from 999c6ff to 31b1929 Compare May 28, 2026 15:35
@fridrik01 fridrik01 requested review from bar-bera and calbera May 28, 2026 15:44
@fridrik01 fridrik01 marked this pull request as ready for review May 28, 2026 18:36
@fridrik01 fridrik01 requested a review from a team as a code owner May 28, 2026 18:36
Copilot AI review requested due to automatic review settings May 28, 2026 18:36
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 28, 2026

Codecov Report

❌ Patch coverage is 57.14286% with 57 lines in your changes missing coverage. Please review.
✅ Project coverage is 60.01%. Comparing base (135d0d1) to head (e23dc05).

Files with missing lines Patch % Lines
node-core/components/preconf_client.go 0.00% 20 Missing ⚠️
cli/flags/flags.go 0.00% 15 Missing ⚠️
beacon/preconf/server.go 81.63% 5 Missing and 4 partials ⚠️
beacon/preconf/client.go 61.53% 4 Missing and 1 partial ⚠️
node-core/components/preconf_server.go 0.00% 5 Missing ⚠️
beacon/preconf/config.go 83.33% 2 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@               Coverage Diff               @@
##           preconf-dev    #3115      +/-   ##
===============================================
+ Coverage        59.72%   60.01%   +0.29%     
===============================================
  Files              384      384              
  Lines            19929    20055     +126     
===============================================
+ Hits             11902    12036     +134     
+ Misses            7047     7028      -19     
- Partials           980      991      +11     
Files with missing lines Coverage Δ
beacon/preconf/loader.go 67.12% <100.00%> (+7.12%) ⬆️
beacon/preconf/config.go 89.28% <83.33%> (-10.72%) ⬇️
beacon/preconf/client.go 21.87% <61.53%> (+21.87%) ⬆️
node-core/components/preconf_server.go 19.51% <0.00%> (-2.72%) ⬇️
beacon/preconf/server.go 75.31% <81.63%> (+22.73%) ⬆️
cli/flags/flags.go 0.00% <0.00%> (ø)
node-core/components/preconf_client.go 17.02% <0.00%> (-12.61%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread beacon/preconf/config.go Outdated
Comment thread node-core/components/preconf_client.go Outdated
Comment thread beacon/preconf/README.md Outdated
Copy link
Copy Markdown
Contributor

@calbera calbera left a comment

Choose a reason for hiding this comment

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

generally lgtm, left some nits + will review again.

Some potential followups from claude:

  • No mTLS / client certificates. The client is authenticated at the app layer via JWT; TLS only authenticates the server. For this threat model that's adequate; mTLS would be defense-in-depth, a fine follow-up.
  • No rate-limiting / the JWT check is O(n) HMAC over all validator secrets before the whitelist/proposer checks. Pre-existing, but this PR's whole premise is internet exposure, which makes an unauthenticated-request amplification slightly more relevant. Follow-up, not a blocker.

@fridrik01
Copy link
Copy Markdown
Contributor Author

generally lgtm, left some nits + will review again.

Some potential followups from claude:

  • No mTLS / client certificates. The client is authenticated at the app layer via JWT; TLS only authenticates the server. For this threat model that's adequate; mTLS would be defense-in-depth, a fine follow-up.
  • No rate-limiting / the JWT check is O(n) HMAC over all validator secrets before the whitelist/proposer checks. Pre-existing, but this PR's whole premise is internet exposure, which makes an unauthenticated-request amplification slightly more relevant. Follow-up, not a blocker.

mTLS is not required imo, but the others are part of https://berachain.clickup.com/t/9014124274/86b9exmww and https://berachain.clickup.com/t/9014124274/86b9exmz9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants