haneel-kumar commented on issue #790: URL: https://github.com/apache/arrow-java/issues/790#issuecomment-3024529786
Hi @elbinpallimalilibm @lidavidm , After a thorough investigation and the creation of a standalone test case, we have confirmed that the observed behavior is not a defect but is the intended and correct functionality of the Arrow Flight API. **Core Finding: The `.useTls()` Method is the Decisive Factor** Our testing revealed that with `Location.forGrpcInsecure(...)` providing certificates via .clientCertificate(...) and .trustedCertificates(...) is not sufficient on its own to override the insecure setting. The connection will fail unless the `.useTls()` method is also called on the `FlightClient.Builder`. The `.useTls()` method acts as the mandatory switch that activates the security configuration, instructing the client to disregard the insecure location and proceed with a full TLS handshake using the provided credentials. **Evidence and Underlying Mechanism** The logic is supported by both the Arrow Flight source code and the underlying gRPC principles: 1. **Arrow Flight API Design:** The [FlightClient.java source code](https://github.com/apache/arrow-java/blob/main/flight/flight-core/src/main/java/org/apache/arrow/flight/FlightClient.java) clearly shows that `.useTls()` is the designated method for enabling transport security on the client. It is not an optional call. <img width="608" alt="Image" src="https://github.com/user-attachments/assets/bfebc5a8-bfc6-460c-ad8a-9a841bc0ceab" /> 2. **gRPC Security Model:** Arrow's `Location.forGrpcInsecure(...)` signals an intention to use a plaintext connection by calling gRPC's internal `usePlaintext()` method. As per the official [gRPC-java documentation](https://grpc.github.io/grpc-java/javadoc/io/grpc/netty/NettyChannelBuilder.html), this plaintext setting is only overridden when a secure context is both provided and explicitly activated. In the Arrow Flight API, the `.useTls()` call is that explicit activation. <img width="720" alt="Image" src="https://github.com/user-attachments/assets/8af6d0cc-9d6c-4f68-adbe-ce14fcaac4f6" /> <img width="788" alt="Image" src="https://github.com/user-attachments/assets/baaabce2-542e-48ed-8b65-433fef9459bf" /> **For example:** > If I provide a forGrpcInsecure location and provide certificates, but do not call .useTls() — will it go secure or not? **Answer:** It will not go secure, and the connection will fail. **Explanation:** - You first provide a Location.forGrpcInsecure(...). This sets the primary intention to be an unencrypted, plaintext connection. - You then provide the certificates. This loads the security materials into the builder, but it does not activate them. - Since you do not call .useTls(), the builder's original instruction to use a plaintext connection is never overridden. The client will attempt to establish an unencrypted connection to a server that is expecting a secure TLS handshake, causing the connection to be rejected and fail. <img width="1097" alt="Image" src="https://github.com/user-attachments/assets/2271d1ef-2b92-4c07-a319-37b448e2f9ed" /> **Conclusion** The behavior is correct and by design. The MtlsTest.java test case developed during this investigation serves as a reproducible proof of this principle. The final recommendation is to update the project's documentation to clarify that when using an insecure location, in establishing a secure connection requires both providing the necessary certificates and explicitly calling the .useTls() method on the client builder. This will prevent future confusion and ensure users configure their clients correctly. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: github-unsubscr...@arrow.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org