Summary
When tls.enabled is set to false (or left unset), the gRPC client in fxconfig silently downgrades to a completely plaintext connection with zero certificate validation. Because the default value of enabled is false, every fresh deployment that doesn't explicitly opt into TLS is running without any transport security out of the box.
Where
File: tools/fxconfig/internal/client/client.go, lines 42-44
Function: createSecOpts
if !tlsConfig.IsEnabled() {
return &secOpts, nil // returns empty SecureOptions → UseTLS = false → plaintext
}
This returns a bare comm.SecureOptions{} struct - UseTLS stays false, no root CAs are loaded, and the resulting grpc.ClientConn is dialed without any transport credentials.
The IsEnabled() check lives in tools/fxconfig/internal/config/config.go:107-111 and defaults to false when the pointer is nil.
Why this matters
1.No encryption in transit. Channel payloads (transaction proposals, block events, notification streams) are sent as cleartext over the network.
2.No server identity verification. Without root CA certificates, there is nothing stopping a man-in-the-middle from impersonating the orderer, query, or notification service.
3.Unsafe default. The enabled field defaults to false, which means operators who forget to (or don't know to) flip the flag are silently running insecure. This is especially risky in cloud or multi-tenant environments where network trust boundaries are not guaranteed.
Steps to reproduce
1.Create or use a config file where tls.enabled is either explicitly false or simply omitted.
2.Start fxconfig — all three clients will connect over plaintext gRPC.
3.Inspect the wire traffic (e.g., with tcpdump or Wireshark) to confirm payloads are unencrypted.
Suggested fix
A few options to consider (not mutually exclusive):
Default enabled to true. Flip the struct tag default from "false" to "true" so TLS is on unless an operator deliberately disables it. This is the "secure by default" approach.
Log a warning when TLS is off. If keeping false as the default is intentional for local dev, emit a clear warning at startup (e.g., "TLS is disabled for <service> — connections are not encrypted") so operators are aware.
Require an explicit opt-out. Instead of silently accepting a missing enabled field, require the operator to set enabled: false explicitly if they truly want plaintext, and error on nil.
Summary
When
tls.enabledis set tofalse(or left unset), the gRPC client infxconfigsilently downgrades to a completely plaintext connection with zero certificate validation. Because the default value ofenabledisfalse, every fresh deployment that doesn't explicitly opt into TLS is running without any transport security out of the box.Where
File:
tools/fxconfig/internal/client/client.go, lines 42-44Function:
createSecOptsThis returns a bare comm.SecureOptions{} struct - UseTLS stays false, no root CAs are loaded, and the resulting grpc.ClientConn is dialed without any transport credentials.
The IsEnabled() check lives in tools/fxconfig/internal/config/config.go:107-111 and defaults to false when the pointer is nil.
Why this matters
1.No encryption in transit. Channel payloads (transaction proposals, block events, notification streams) are sent as cleartext over the network.
2.No server identity verification. Without root CA certificates, there is nothing stopping a man-in-the-middle from impersonating the orderer, query, or notification service.
3.Unsafe default. The enabled field defaults to false, which means operators who forget to (or don't know to) flip the flag are silently running insecure. This is especially risky in cloud or multi-tenant environments where network trust boundaries are not guaranteed.
Steps to reproduce
1.Create or use a config file where
tls.enabledis either explicitlyfalseor simply omitted.2.Start
fxconfig— all three clients will connect over plaintext gRPC.3.Inspect the wire traffic (e.g., with
tcpdumpor Wireshark) to confirm payloads are unencrypted.Suggested fix
A few options to consider (not mutually exclusive):
Default
enabledtotrue. Flip the struct tag default from"false"to"true"so TLS is on unless an operator deliberately disables it. This is the "secure by default" approach.Log a warning when TLS is off. If keeping false as the default is intentional for local dev, emit a clear warning at startup (e.g.,
"TLS is disabled for <service> — connections are not encrypted") so operators are aware.Require an explicit opt-out. Instead of silently accepting a missing
enabledfield, require the operator to setenabled: falseexplicitly if they truly want plaintext, and error onnil.