What is the SASL/OAUTHBEARER mechanism in Kafka, and how does a client authenticate with it?
answer
- bearer token = JWT, possession grants access
- sasl.mechanism=OAUTHBEARER + SASL_SSL
- login callback acquires, validator callback verifies
- client-credentials grant to token endpoint
- principal from sub claim
basics
~10 sOAUTHBEARER 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 sSASL/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
Know it means token-based login: client presents an OAuth2 bearer token (a JWT) instead of a password, and Kafka validates it.
Be able to name the configs (sasl.mechanism, token endpoint, jwks endpoint) and describe the login-vs-validator callback split.
Explain the full handshake, principal extraction from claims, JWKS signature verification, and why SASL_SSL is required.
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.