Affects: pulsar 6.8.0 (verified at tag v6.8.0 and at master, commit 95a0d73).
Summary
CommandConnect is built without populating feature_flags, so the broker is never told the
client supports auth refresh. The broker therefore does not send CommandAuthChallenge to
rotate credentials in-flight, and short-lived tokens (OAuth2/JWT) take the connection down at
expiry instead of being refreshed transparently.
Detail
src/connection.rs:1457 (tag v6.8.0):
connect: Some(proto::CommandConnect {
auth_method_name,
auth_data,
proxy_to_broker_url,
client_version: proto::client_version(),
protocol_version: Some(12),
..Default::default() // <-- feature_flags left as None
}),
PulsarApi.proto:290-297:
optional FeatureFlags feature_flags = 10;
message FeatureFlags {
optional bool supports_auth_refresh = 1 [default = false];
...
}
With feature_flags unset, supports_auth_refresh is false.
What makes this cheap to fix
The client-side machinery already exists and is wired up. The connection already has an
auth-challenge channel and handler:
src/connection.rs:239-241 — receives and dispatches RequestKey::AuthChallenge
src/connection.rs:649-654 — auth_challenge() sends the response
src/connection.rs:1287, 1335 — channel construction and the spawned handler task
So the client can already handle a challenge; it simply never tells the broker it can, which
means the broker never sends one. The fix is to populate feature_flags with
supports_auth_refresh: true.
Secondary observation
The same struct hardcodes protocol_version: Some(12), which is well behind current brokers.
Worth confirming whether auth-refresh negotiation is additionally gated on protocol version,
and whether that constant should be raised — possibly a separate issue.
Reproduction
Not yet demonstrated behaviorally. Reported by a user running short-lived OAuth2 tokens
against StreamNative Cloud, who observed client disconnection at token expiry rather than
rotation.
Reported by customer (Private Cloud, FedRAMP environment) while moving from long-lived auth tokens to short-lived OAuth2/JWT. Internal tracking: eng-support-tickets#4823.
Affects:
pulsar6.8.0 (verified at tagv6.8.0and atmaster, commit95a0d73).Summary
CommandConnectis built without populatingfeature_flags, so the broker is never told theclient supports auth refresh. The broker therefore does not send
CommandAuthChallengetorotate credentials in-flight, and short-lived tokens (OAuth2/JWT) take the connection down at
expiry instead of being refreshed transparently.
Detail
src/connection.rs:1457(tagv6.8.0):PulsarApi.proto:290-297:With
feature_flagsunset,supports_auth_refreshisfalse.What makes this cheap to fix
The client-side machinery already exists and is wired up. The connection already has an
auth-challenge channel and handler:
src/connection.rs:239-241— receives and dispatchesRequestKey::AuthChallengesrc/connection.rs:649-654—auth_challenge()sends the responsesrc/connection.rs:1287, 1335— channel construction and the spawned handler taskSo the client can already handle a challenge; it simply never tells the broker it can, which
means the broker never sends one. The fix is to populate
feature_flagswithsupports_auth_refresh: true.Secondary observation
The same struct hardcodes
protocol_version: Some(12), which is well behind current brokers.Worth confirming whether auth-refresh negotiation is additionally gated on protocol version,
and whether that constant should be raised — possibly a separate issue.
Reproduction
Not yet demonstrated behaviorally. Reported by a user running short-lived OAuth2 tokens
against StreamNative Cloud, who observed client disconnection at token expiry rather than
rotation.
Reported by customer (Private Cloud, FedRAMP environment) while moving from long-lived auth tokens to short-lived OAuth2/JWT. Internal tracking: eng-support-tickets#4823.