skip to content

SASL OAUTHBEARER and Delegation Tokens

OAuth/OIDC bearer tokens and delegation tokens as short-lived Kafka credentials. Interviewers ask it as the modern alternative to shipping static passwords to every job.

part ofApache Kafkaoverview, primer and where to startread it →
on this pageshow

questions

5

What is the SASL/OAUTHBEARER mechanism in Kafka, and how does a client authenticate with it?

level: juniorimportance: must knowfreq 55%

answer

  1. bearer token = JWT, possession grants access
  2. sasl.mechanism=OAUTHBEARER + SASL_SSL
  3. login callback acquires, validator callback verifies
  4. client-credentials grant to token endpoint
  5. principal from sub claim

basics

~10 s

OAUTHBEARER is a Kafka SASL mechanism where the client presents an OAuth2 bearer token (usually a JWT) instead of a username/password. Kafka validates the token to authenticate the connection.

solid answer

~40 s

SASL/OAUTHBEARER lets a Kafka client authenticate by presenting an OAuth2 bearer token — typically a signed JWT obtained from an identity provider (IdP) such as Keycloak, Okta, or Azure AD. You set `sasl.mechanism=OAUTHBEARER` and `security.protocol=SASL_SSL` (or SASL_PLAINTEXT). A login callback handler (`sasl.login.callback.handler.class`) acquires the token, usually via the OAuth2 client-credentials grant against a token endpoint. On the broker side, a validation callback verifies the token's signature, issuer, audience, and expiry. The authenticated principal is derived from a JWT claim (e.g. `sub`). Tokens are short-lived, so the client library re-acquires them before expiry. This decouples Kafka auth from static credentials and centralizes identity in the IdP.

go deeper

for a junior

Know it means token-based login: client presents an OAuth2 bearer token (a JWT) instead of a password, and Kafka validates it.

for a middle

Be able to name the configs (sasl.mechanism, token endpoint, jwks endpoint) and describe the login-vs-validator callback split.

for a senior

Explain the full handshake, principal extraction from claims, JWKS signature verification, and why SASL_SSL is required.

for a principal

Reason about IdP integration topology, token lifetime vs. connection longevity, and trade-offs versus mTLS or SCRAM at fleet scale.

## What problem it solves Kafka supports several SASL (Simple Authentication and Security Layer) mechanisms: PLAIN (username/password), SCRAM (salted challenge-response), GSSAPI (Kerberos), and OAUTHBEARER. **OAUTHBEARER** integrates Kafka with modern OAuth2 / OpenID Connect (OIDC) identity providers so that clients authenticate with a short-lived **bearer token** rather than a long-lived password stored in config. A **bearer token** is a credential where mere possession grants access ("bearer" = whoever holds it). In practice it is almost always a **JWT** (JSON Web Token): a base64url-encoded, signed JSON document with three parts — header, payload (claims), signature — joined by dots. ## The authentication flow 1. The client is configured with `sasl.mechanism=OAUTHBEARER` and `security.protocol=SASL_SSL`. 2. A **login callback handler** runs on the client. Apache Kafka ships `org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginCallbackHandler`, which performs an OAuth2 **client-credentials grant**: it POSTs `client_id` + `client_secret` to the IdP's token endpoint (`sasl.oauthbearer.token.endpoint.url`) and gets back an access token. 3. The client sends the token to the broker as part of the SASL handshake. 4. The broker runs a **server/validation callback handler** (`OAuthBearerValidatorCallbackHandler`) that validates the token: checks the signature against the IdP's JWKS (JSON Web Key Set) public keys, verifies `iss` (issuer), `aud` (audience), `exp` (expiry), and extracts the **principal** from a configured claim (default `sub`, overridable with `sasl.oauthbearer.sub.claim.name`). 5. If valid, the connection is authenticated and the principal flows into Kafka's authorizer (ACLs) for authorization. ## Configs at a glance - `sasl.mechanism=OAUTHBEARER` - `sasl.login.callback.handler.class` — acquires the token on the client - `sasl.oauthbearer.token.endpoint.url` — IdP token endpoint - `sasl.oauthbearer.jwks.endpoint.url` — broker fetches public keys here to verify signatures - `sasl.jaas.config` — carries `clientId`/`clientSecret` (or `scope`) ## Key properties - **Short-lived tokens**: the client library refreshes the token before expiry; the long-lived secret is the IdP client secret, not the token itself. - **Centralized identity**: rotation, revocation, and policy live in the IdP, not in Kafka. - **Transport security matters**: because a bearer token grants access to anyone holding it, you must use TLS (`SASL_SSL`) in production so the token is not exposed on the wire. ## Edge cases - The built-in handlers were not always available — early on you needed a third-party library (e.g. Strimzi's `kafka-oauth`). The native handlers became production-ready over time (KIP-768 added the OIDC-compliant validator and login handlers). - An **unsecured** mode exists (`OAuthBearerUnsecuredLoginCallbackHandler`) for testing only — it issues unsigned tokens and must never be used in production.

  • Why must you use SASL_SSL rather than SASL_PLAINTEXT with OAUTHBEARER in production?
    A bearer token grants access to anyone who holds it. Without TLS the token travels in cleartext and can be sniffed and replayed, so transport encryption is mandatory.
  • Which Apache Kafka class performs the OAuth2 client-credentials login on the client side?
    org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginCallbackHandler, configured via sasl.login.callback.handler.class.

saying these in an interview costs you the question

  • Saying OAUTHBEARER uses a static username/password like PLAIN — it uses a token from an IdP.
  • Claiming the token is long-lived and never refreshed — tokens are short-lived and re-acquired before expiry.
  • Thinking OAUTHBEARER provides encryption — it is authentication only; TLS comes from SASL_SSL.
  • Using OAuthBearerUnsecuredLoginCallbackHandler in production.

context

open as a page

How does a Kafka broker validate an OAUTHBEARER JWT, and which sasl.oauthbearer.* configs control it?

level: seniorimportance: must knowfreq 45%

basics

~10 s

The broker fetches the IdP's public keys from a JWKS endpoint and checks the JWT's signature, issuer, audience, and expiry. Configs like sasl.oauthbearer.jwks.endpoint.url, expected.issuer, expected.audience, and sub.claim.name control this.

open as a page

How does a Kafka client refresh its OAUTHBEARER token, and what happens to a long-lived connection when the token expires?

level: middleimportance: should knowfreq 35%

basics

~20 s

The 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).

open as a page

What are Kafka delegation tokens (KIP-48), and what problem do they solve for distributed workers and jobs?

level: seniorimportance: should knowfreq 30%

basics

~20 s

Delegation tokens are lightweight shared-secret credentials a client first authenticates (e.g. via Kerberos or OAUTHBEARER), then requests from the broker. Workers/tasks use the token to authenticate to Kafka without distributing the original credential, simplifying secret distribution in distributed jobs.

open as a page

For a multi-tenant job platform that runs short-lived jobs against Kafka, how would you choose between OAUTHBEARER, delegation tokens, and per-tenant credentials for worker/job impersonation?

level: principalimportance: nice to knowfreq 18%

basics

~20 s

Use OAUTHBEARER when each job/worker can talk to your IdP for its own short-lived token (best for centralized identity and revocation). Use delegation tokens when a coordinator authenticates once and must fan out cheap, revocable credentials to many executors without contacting the IdP per task.

open as a page