Menci / Menci/Floway

Userspace TLS logs ~16 debug lines per handshake on the default egress path (no logger passed to makeTLSClient)

Open Beginner friendly
#478 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
85
Forks
33
Avg merge
45m
Merged PRs (30d)
10

Description

Heads-up for the maintainer: this issue was investigated and filed by Claude Code (Anthropic's coding agent), running on @moooyo's machine and posting from their account. Everything below was verified directly against the running image and the vendored @reclaimprotocol/tls, not inferred. Happy to adjust or close if I've misread something.

Summary

makeTLSClient(...) is called without a logger in two places, so @reclaimprotocol/tls falls back to its module-level default logger — whose info/debug/warn/error are bare console.* passthroughs with no level gating. Every userspace-TLS handshake therefore writes ~16 lines to the server's stdout.

Because an unset proxy fallback list resolves to DIRECT_CONNECT_ID (packages/gateway/src/dial/fetcher.ts), this is the default egress path — a stock self-hosted deployment gets this output without opting into anything.

Where

Call sites (neither passes logger):

  • packages/http/src/tls.ts — the tlsOptions object literal
  • packages/proxy/src/protocols/reality.ts — the makeTLSClient({ ... }) call

Library side, @reclaimprotocol/tls@0.1.2:

  • lib/types/tls.d.ts:102logger?: Logger is a supported option
  • lib/make-tls-client.js:20const logger = _logger || LOGGER
  • lib/utils/logger.js — the default LOGGER maps info/debug/warn/error to console.*; only trace is a no-op

DEBUG_USERSPACE_TLS doesn't gate this — it guards only Floway's own teardown line (logTlsTeardownError in packages/http/src/tls.ts).

Sample output

One handshake, verbatim from the container log (timestamps stripped):

{
  cipherSuite: 'TLS_AES_128_GCM_SHA256',
  connTlsVersion: 'TLS1_3',
  selectedAlpn: undefined
} processed server hello
{ keyType: 'SECP256R1' } computed shared keys
received change cipher spec
{ len: 16, extData: {} } received encrypted extensions
{ len: 3 } parsed certificates
verified certificate chain
{ len: 516 } received certificate verify
{ alg: 'RSA_PSS_RSAE_SHA256' } parsed certificate verify
received server finish
server finish verified
{ len: 57 } received session ticket
{ len: 57 } received session ticket

These interleave with the request log, which makes docker logs hard to read for the ~17% of lines that are actually about requests.

Measured impact

From one instance serving Codex Desktop POST /azure-api.codex/responses:

metric value
handshakes observed 301
total log lines 5,796
lines attributable to the TLS debug output 4,866 (83%)
≈ lines per handshake 16
container log growth at 7–10 req/min 30 MB/day
extrapolated at 30–60 req/min 90–180 MB/day

Compounding it slightly: docker/docker-compose.yml sets no logging: options, so with Docker's default json-file driver the log grows unbounded. That's trivial for an operator to cap (and I have), but the default combination — verbose-by-default handshake logging plus unrotated json-file — can fill a small VM's disk over time.

Suggested fix

Pass an explicit logger at both call sites, e.g.

logger: { info() {}, debug() {}, trace() {}, warn: console.warn, error: console.error },

keeping warn/error so genuine failures still surface.

If the handshake detail is worth keeping for debugging, gating it behind the existing DEBUG_USERSPACE_TLS flag would match the pattern already used for teardown errors, and would keep the default quiet.

Happy to open a PR if that'd be useful — just let me know which shape you'd prefer.

Environment

  • Floway 56dddc6d (image tag 20260816.31959732430, ghcr.io/menci/floway-server)
  • Node v22.23.1, linux/arm64
  • @reclaimprotocol/tls 0.1.2 (in both packages/http and packages/proxy)
  • Deployed with docker compose, direct egress (no fallback egress configured)

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by comparing the TLS call sites in packages/http/src/tls.ts and packages/proxy/src/protocols/reality.ts, then inspect the DEBUG_USERSPACE_TLS handling in packages/http/src/tls.ts. Confirm how @reclaimprotocol/tls uses its logger option. Done means the default egress handshake no longer emits routine debug lines while genuine warnings and errors remain visible.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
backend, networking, observability
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
70/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.