How does a Kafka client refresh its OAUTHBEARER token, and what happens to a long-lived connection when the token expires?
answer
- auth happens once at connect; token expiry doesn't drop live conns
- ExpiringCredentialRefreshingLogin background refresh
- refresh.window.factor 0.8, buffer.seconds 300
- connections.max.reauth.ms = KIP-368 re-auth
- no re-auth => expired token still works on open connection
basics
~20 sThe client's login manager proactively re-acquires a new token before the old one expires, based on a fraction of the token lifetime. Established connections stay open after a token expires; expiry mainly gates new connections (re-authentication can enforce expiry on live ones).
solid answer
~40 sKafka's `ExpiringCredentialRefreshingLogin` schedules a background refresh that re-runs the login callback to fetch a fresh token before the current one expires. The schedule is governed by `sasl.login.refresh.window.factor` (refresh after ~80% of lifetime), `sasl.login.refresh.window.jitter`, and `sasl.login.refresh.min/buffer.seconds`. Crucially, an already-authenticated connection is NOT torn down when its token expires — Kafka authenticates once at connect time. To bound a session's lifetime to the token, you enable **server-side re-authentication** with `connections.max.reauth.ms` (KIP-368): the broker tells clients to re-authenticate before that interval, and the refreshed token is presented. Without re-auth, a long-lived producer can outlive its token until the connection drops and must reconnect, at which point a valid token is required again.
go deeper
Know the client gets a fresh token before the old one expires.
Explain proactive background refresh (window.factor/buffer) and that expiry doesn't drop live connections by default.
Bring in connections.max.reauth.ms / KIP-368 as the lever to enforce token expiry on long-lived sessions, and the revocation gap.
Design session-bounding policy: token lifetime vs reauth interval vs IdP load, and revocation guarantees for impersonated worker/job sessions.
## Two different lifetimes There are two clocks to keep separate: 1. The **token lifetime** (`exp` in the JWT) — how long a token is valid. 2. The **connection lifetime** — how long a TCP/SASL connection stays open. Kafka authenticates **once at connection establishment**. So by default a connection that authenticated with a valid token keeps working even after that token expires, until the connection is closed for some other reason. ## Client-side token refresh The client must keep a *valid* token on hand so that *new* connections (and re-authentication) succeed. Kafka's `ExpiringCredentialRefreshingLogin` runs a background thread that re-invokes the login callback handler to mint a fresh token before the current one expires. Relevant client configs: - `sasl.login.refresh.window.factor` (default 0.8) — refresh after ~80% of token lifetime elapses. - `sasl.login.refresh.window.jitter` (default 0.05) — random jitter to avoid a thundering herd of refreshes. - `sasl.login.refresh.min.period.seconds` (default 60) — minimum wait between refreshes. - `sasl.login.refresh.buffer.seconds` (default 300) — refresh at least this long before expiry. - Connection/retry tuning for the token endpoint: `sasl.login.connect.timeout.ms`, `sasl.login.read.timeout.ms`, `sasl.login.retry.backoff.ms`, `sasl.login.retry.backoff.max.ms`. ## Bounding the session to the token: re-authentication (KIP-368) If you want an expired token to actually cut off access on an existing connection, configure the broker with `connections.max.reauth.ms`. When set (e.g. 3600000), the broker instructs each SASL connection to **re-authenticate** before that window elapses. The client transparently presents its (refreshed) token. If the client can't re-authenticate with a valid token, the broker closes the connection. This is what enforces token expiry on long-lived connections and is essential when you rely on token expiry for revocation/impersonation bounds. ## What goes wrong - **Refresh failures**: if the IdP token endpoint is down when a refresh is due, the client may end up with an expired token; new connections then fail. Retry/backoff configs and IdP availability matter. - **No re-auth configured**: operators sometimes assume revoking/expiring a token immediately kills active sessions. It does not — without `connections.max.reauth.ms`, the existing connection persists. This is a frequent security gap. - **Window too tight**: very short token lifetimes (e.g. 60s) with default refresh factors can cause constant refresh churn and load on the IdP. ## Summary mental model The login layer keeps a fresh token available; `connections.max.reauth.ms` is the lever that makes token expiry meaningful for live connections.
- An admin revokes a token at the IdP. Does that immediately disconnect an active producer?No. Kafka authenticates once at connect time. Unless connections.max.reauth.ms (KIP-368) forces periodic re-authentication, the open connection keeps working until it drops for another reason. Revocation/expiry only bites on new connections or at re-auth.
saying these in an interview costs you the question
- Claiming an expiring token automatically severs existing connections — it doesn't without re-auth.
- Saying the client refreshes only when a request fails — refresh is proactive, scheduled before expiry.
- Ignoring connections.max.reauth.ms when discussing how to bound session lifetime to token lifetime.
- Confusing token lifetime with connection lifetime.