akshatha ramesh created KAFKA-21143:
---------------------------------------

             Summary: Server-only OAUTHBEARER listener with private JWKS CA 
triggers token login and fails broker startup
                 Key: KAFKA-21143
                 URL: https://issues.apache.org/jira/browse/KAFKA-21143
             Project: Kafka
          Issue Type: Bug
          Components: security
    Affects Versions: 4.2.2
         Environment: Apache Kafka 4.2.0
            Reporter: akshatha ramesh


h3. Problem

A broker configured with an external {{SASL_SSL/OAUTHBEARER}} listener can fail 
during startup when the broker is intended to act only as an OAuth token 
validator and the JWKS endpoint requires a private CA.

Example topology:

 

{{Inter-broker traffic:
  PLAINTEXT

External listener:
  SASL_SSL + OAUTHBEARER

External clients:
  obtain JWTs from an external IdP and present them to Kafka

Kafka broker:
  validates incoming JWTs using the IdP JWKS endpoint
  does not need to obtain an OAuth token for itself}}

The JWKS endpoint uses HTTPS with a private CA, so trust configuration is 
supplied:

 

{{listener.name.oam.oauthbearer.sasl.jaas.config=\
org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \
ssl.truststore.location="/path/to/idp-ca.crt" \
ssl.truststore.type="PEM";

listener.name.oam.oauthbearer.sasl.server.callback.handler.class=\
org.apache.kafka.common.security.oauthbearer.OAuthBearerValidatorCallbackHandler

listener.name.oam.oauthbearer.sasl.oauthbearer.jwks.endpoint.url=\
https://<idp>/.../certs

security.inter.broker.protocol=PLAINTEXT}}

During broker startup, initialization of the external SASL listener reaches 
{{OAuthBearerLoginModule.login()}} and fails:

 

{{kafka.network.DataPlaneAcceptor.configure
...
org.apache.kafka.common.network.SaslChannelBuilder.configure
...
org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule.login

javax.security.auth.login.LoginException:
An internal error occurred while retrieving token from callback handler}}
h3. Existing tokenless server-side behavior

KAFKA-7462 addressed the case where {{OAuthBearerLoginModule}} is initialized 
on a broker even though OAUTHBEARER is not being used for inter-broker 
authentication.

The default {{OAuthBearerUnsecuredLoginCallbackHandler}} currently identifies 
the tokenless server-side case using:

 

{{if (moduleOptions.isEmpty()) \{
    callback.token(null);
    return;
}}}

{{OAuthBearerLoginModule}} accepts this tokenless login:

 

{{identifyToken();

if (tokenRequiringCommit != null)
    identifyExtensions();
else
    log.debug("Logged in without a token...");}}

Therefore an OAUTHBEARER broker listener with no broker OAuth client role can 
start when the JAAS module options are empty.
h3. Problem with private JWKS CA configuration

For a validation-only listener whose JWKS endpoint requires a private CA, the 
JAAS options are not empty:

 

{{ssl.truststore.location="/path/to/idp-ca.crt"
ssl.truststore.type="PEM"}}

As a result:

 

{{moduleOptions.isEmpty() == false}}

even though these options configure TLS trust for JWKS validation and do not 
indicate that the broker needs to acquire an OAuth token.

The default login callback therefore does not take the KAFKA-7462 tokenless 
path. It proceeds into the login/token creation path, and broker startup fails 
when no broker OAuth principal/token-acquisition configuration exists.
h3. Expected behavior

A broker should be able to operate with:

 

{{inter-broker = PLAINTEXT
external listener = SASL_SSL/OAUTHBEARER
broker role = validate incoming JWT only
JWKS endpoint = HTTPS with private CA}}

without requiring the broker to obtain an OAuth token for that listener.

Providing TLS trust configuration required for the JWKS endpoint should not by 
itself cause the listener to be treated as requiring broker-side OAuth 
login/token acquisition.
h3. Question / Possible gap

Is there an intended supported configuration that allows JWKS TLS trust options 
to be supplied while retaining the tokenless server-side behavior introduced by 
KAFKA-7462?

If not, the current {{moduleOptions.isEmpty()}} check appears unable to 
distinguish:

 

{{JAAS options representing broker OAuth login configuration}}

from:

 

{{JAAS options required only for server-side JWKS TLS trust}}

which prevents the tokenless server-only OAUTHBEARER use case when the JWKS 
endpoint uses a private CA.

Related report:
[https://github.com/confluentinc/kafka/issues/2160]



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to