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)