viirya commented on PR #92:
URL: 
https://github.com/apache/spark-connect-rust/pull/92#issuecomment-5486670118

   Post-merge note — I went through this after it landed on master (`7116d72`) 
and branch-4.2 (`30a2d71`). Both fixes are right, and I traced the mechanisms 
rather than taking the description's word for it: `metadata` (`client.rs:60`) → 
`_attach_metadata` (`client.rs:836-842`) inserts each pair on every RPC, and 
`with_new_session_id` (`client.rs:153`) clones it, so "propagates to every 
request including the reattach stream" checks out. The `with_native_roots()` 
diagnosis is accurate too — since tonic 0.11 the `tls-native-roots` feature 
only pulls in `rustls-native-certs` without installing it into 
`ClientTlsConfig`, so the handshake had no anchors and the 15-retry backoff 
turned that failure into an apparent hang. Sweeping the repo, TLS setup and 
token attachment each have exactly one site, so there's no sibling instance 
either fix missed. And converting `test_token_bearer_in_metadata` from "the 
token parses" to "the header is attached" closes a genuinely vacuous test — it 
pa
 sses offline, since `connect_lazy()` means `connect()` needs no live server.
   
   **One thing the fix introduces, though: the bearer token can now go out in 
cleartext.** `secure()` is `use_ssl() || token().is_some()` (`channel.rs:159`), 
but the scheme is chosen from `use_ssl()` alone (`client.rs:88`), and the new 
header is attached unconditionally (`client.rs:124`) without consulting either. 
So `sc://example.com/;token=SECRET` sends `Authorization: Bearer SECRET` over 
plain `http://`. I confirmed it with a probe against the merged commit:
   
   ```
   PROBE use_ssl=false secure=true auth_header=Some(("authorization", "Bearer 
SECRET123"))
   ```
   
   The reference client can't reach that state. `toChannel()` 
(`core.py:648-665`) is three-way: no token → insecure channel; token with 
`use_ssl=false` **and host == localhost** → `local_channel_credentials()`; 
everything else → `ssl_channel_credentials()`. The token is only ever attached 
via `grpc.access_token_call_credentials`, and grpcio refuses call credentials 
on an insecure channel by design — precisely to stop credentials leaking in the 
clear. So upstream's token always rides an encrypted (or loopback) channel.
   
   Worth noting `secure()` is computed here but never actually gates channel 
construction — which is the same "declared but never applied" shape as 
SPARK-59032 (parsed keepalive never applied) and SPARK-59037 (128 MiB cap 
declared but unused), and indeed as the token half of this very PR. Also 
relevant: `token()` falls back to the `SPARK_CONNECT_AUTHENTICATE_TOKEN` env 
var (`channel.rs:154`), so a connection string with no `token` at all can still 
take this path — the exposure is wider than the connection-string case alone.
   
   I'd suggest matching upstream's semantics: when a token is present with 
`use_ssl=false` and the host is not `localhost`/`127.0.0.1`, return an error 
naming `use_ssl=true` rather than silently downgrading. Keeping the localhost 
case working matters for local development (upstream allows it too), just as an 
explicit exception. Failing loudly is better than a silent cleartext send: a 
mistyped connection string currently leaks the credential, whereas an error 
message gets it fixed on the spot.
   
   To be clear, I don't think this needs a revert — the two bugs it fixes are 
real and the fixes are correct. This is a follow-up.
   
   Two minor things while I'm here. The header key is a hardcoded 
`"authorization"`; `http::header::AUTHORIZATION` (or a `const`) would avoid 
re-parsing it through `MetadataKey::from_bytes` on every request. And the test 
asserts on the `client.metadata` field rather than on a real request — legal 
from the in-crate `mod tests`, but it verifies "the value is in the vec", not 
"the header reaches the wire". Building a `Request`, calling 
`_attach_metadata`, and checking `req.metadata()` would survive a future change 
to the insert logic. Neither is worth a follow-up on its own.
   


-- 
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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to