confluentinc / confluentinc/confluent-kubernetes-examples
Unable to fetch Bearer token from Keycloak
- Dominant language
- Shell
- Stars
- 72
- Forks
- 201
- Avg merge
- 10h 2m
- Merged PRs (30d)
- 2
Description
Hi,
I Cannot get bearer token from Keycloak using the [mtls-rbac-with-sso-oauth](https://github.com/confluentinc/confluent-kubernetes-examples/tree/master/security/mtls-rbac-with-sso-oauth) example
I tested that the realm and client were set up properly via curl
```bash
curl -H "Authorization: Bearer W8V4cqewCy54x4gm7UjhLkk0rrFDi6DT" http://localhost:8080/realms/sso_test/protocol/openid-connect/certs
{"keys":[{"kid":"3a03zu4h_FOFGqiSbayv02tYMpmC9VcG6Dx_ZiZOIU4","kty":"RSA","alg":"RSA-OAEP","use":"enc","n":"sENhBC7WV8scD0bQVq9-fM918d9uz_VMBv6OPpnxpJcbkUEi3hQDqUVQI8e-bgHhlU1saNCrtd2XD3_jrrpChUQ-8k-mCGvQJqQsdy6b4eetEirO8Z5wOQcMG7D8fZqsNs6Nx6Vq_XmLP7AL-k2uEbNEKZgNve7UyMGS1CHno1SYaoTtB7AMRGuM5ubUuNve4QQn8yAGqOERSOU2RJoVSrn46KKqNUUyg70OG10I_4QgBVwMR0u-z9Zca0EtjPsghZwSM3vakwTQDXeuITTuFPvIzbf0zwFE8A-VvpQtNoHfX7MMMLyE35U5Bs4dbe_6uWDR2hVn2jkznxAiSkJ5TQ","e":"AQAB","x5c":["MIICnzCCAYcCBgGWiVSGvTANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDDAhzc29fdGVzdDAeFw0yNTA1MDEwMDUwNDBaFw0zNTA1MDEwMDUyMjBaMBMxETAPBgNVBAMMCHNzb190ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsENhBC7WV8scD0bQVq9+fM918d9uz/VMBv6OPpnxpJcbkUEi3hQDqUVQI8e+bgHhlU1saNCrtd2XD3/jrrpChUQ+8k+mCGvQJqQsdy6b4eetEirO8Z5wOQcMG7D8fZqsNs6Nx6Vq/XmLP7AL+k2uEbNEKZgNve7UyMGS1CHno1SYaoTtB7AMRGuM5ubUuNve4QQn8yAGqOERSOU2RJoVSrn46KKqNUUyg70OG10I/4QgBVwMR0u+z9Zca0EtjPsghZwSM3vakwTQDXeuITTuFPvIzbf0zwFE8A+VvpQtNoHfX7MMMLyE35U5Bs4dbe/6uWDR2hVn2jkznxAiSkJ5TQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBHGabeYjzZF45Lwfd99LElMGxQIdKz8e90xOJOueTLxIVep6xK6f9/Ihpryb/zUa25UJYkNZs2+C93/0WFjXGTl/OnTQuRg2hJlXeecF5wJl8lK51SwzIhLFY/dAI7O37y/Pma/joyGOJRlYfvCQAYBB3rYMgtw8P3FtzO90jIg8oT2dMPdh4P4XoqxNH1GIXMctKdnVN4ffIyEBoim+Zm0OzUnFLHWH0fC2L1uWP/U3QR/aos+PrZyLL0DponYSnHzrRKKRknSFMltEjOwFXKk/RtJfeEbvvfMPek7GRS2+fTsr2rAQ7CAKbjf494OSHSv/O7MjzgSH/Ad1rKyAqe"],"x5t":"k7pDpVT5uy06kSn_iDr3UXvZvzk","x5t#S256":"fTH7sgLmz6Xg9SO_Msq0HqtAP5_OdywYB29AVmIK6R8"},{"kid":"ubqhyrrx9PSPYTFZ7heXgY_BI-JUvNoWpAJVHt8PuM0","kty":"RSA","alg":"RS256","use":"sig","n":"5p_BrUbjQ09gH2DxfEyKbfmIC464F1pjaYhUt_fEHXy_9cxkgIiTp7YSmLbH3gxx7yLnpH0UKj6PLFjVuqPi7zAcQKxLeTgpOuhVvl4u72nP-xep36U5eu7_OLpZSAr2Fx_1dIs6HkFBDrFyEdcCjLGsLRcN5elCuBQ2ZXTqK0LSk5J-CF_WctExPbuHLBnTgkbNYSdRCebXHvVmAQZwevb8TGTRwolnsrRPZqDvL1bVjbkF7IR2ieo2RuO_ipVvIwWM1WgSj4YCTMf4BX2GkNOmMLASZDNU1vfqP_nqsLPsnWALYYvmPRkdnOWkRGm5aRuE2iSF7vqkyBS_qISQXw","e":"AQAB","x5c":["MIICnzCCAYcCBgGWiVSGezANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDDAhzc29fdGVzdDAeFw0yNTA1MDEwMDUwNDBaFw0zNTA1MDEwMDUyMjBaMBMxETAPBgNVBAMMCHNzb190ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5p/BrUbjQ09gH2DxfEyKbfmIC464F1pjaYhUt/fEHXy/9cxkgIiTp7YSmLbH3gxx7yLnpH0UKj6PLFjVuqPi7zAcQKxLeTgpOuhVvl4u72nP+xep36U5eu7/OLpZSAr2Fx/1dIs6HkFBDrFyEdcCjLGsLRcN5elCuBQ2ZXTqK0LSk5J+CF/WctExPbuHLBnTgkbNYSdRCebXHvVmAQZwevb8TGTRwolnsrRPZqDvL1bVjbkF7IR2ieo2RuO/ipVvIwWM1WgSj4YCTMf4BX2GkNOmMLASZDNU1vfqP/nqsLPsnWALYYvmPRkdnOWkRGm5aRuE2iSF7vqkyBS/qISQXwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCbb7Pmn2Efpq7XcQrX5fGG3nA5b+jzgHm4EDR+qP6r5VE+rGKMJ3HLfh++vCZ8Q5o9OS3DDQ78LPlRQtHOLj/O/5Oyyx/goz0Qwm7McT1rhY0lIfmxfnOl4ywcAB3bypwxJVJW0h062hqEk4mxF3UVDT7ANGoYMLp1jyoOJH3/ahEmEsaiaqQzuIidlWfA0/1d8KFigg77w/Mz/87eH9DVnPhhnPkxF92I1bvEdjfqwskl5LhrCP5mXPMdjJ3TkfTcbN47V8sqKuW7lG54Cjnu2CmzlJBW194mwsfL+bv61VEsrN8+8CewV8sDB26epX5wsoP/SPd3GVQetdB5SPow"],"x5t":"EMs6gwvSF4SkwR0dVvNFY5I9Gj0","x5t#S256":"__KqFnFLxby4SfFDmv5J6zvpbE6v-M_7jWO9kdDjf3s"}]}% (beam311) ➜ ~ curl -H "Authorization: Bearer W8V4cqewCy54x4gm7UjhLkk0rrFDi6DT" http://localhost:8080/realms/sso_test/protocol/openid-connect/certs | jq
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2925 100 2925 0 0 26703 0 --:--:-- --:--:-- --:--:-- 26590
{
"keys": [
{
"kid": "3a03zu4h_FOFGqiSbayv02tYMpmC9VcG6Dx_ZiZOIU4",
"kty": "RSA",
"alg": "RSA-OAEP",
"use": "enc",
"n": "sENhBC7WV8scD0bQVq9-fM918d9uz_VMBv6OPpnxpJcbkUEi3hQDqUVQI8e-bgHhlU1saNCrtd2XD3_jrrpChUQ-8k-mCGvQJqQsdy6b4eetEirO8Z5wOQcMG7D8fZqsNs6Nx6Vq_XmLP7AL-k2uEbNEKZgNve7UyMGS1CHno1SYaoTtB7AMRGuM5ubUuNve4QQn8yAGqOERSOU2RJoVSrn46KKqNUUyg70OG10I_4QgBVwMR0u-z9Zca0EtjPsghZwSM3vakwTQDXeuITTuFPvIzbf0zwFE8A-VvpQtNoHfX7MMMLyE35U5Bs4dbe_6uWDR2hVn2jkznxAiSkJ5TQ",
"e": "AQAB",
"x5c": [
"MIICnzCCAYcCBgGWiVSGvTANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDDAhzc29fdGVzdDAeFw0yNTA1MDEwMDUwNDBaFw0zNTA1MDEwMDUyMjBaMBMxETAPBgNVBAMMCHNzb190ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsENhBC7WV8scD0bQVq9+fM918d9uz/VMBv6OPpnxpJcbkUEi3hQDqUVQI8e+bgHhlU1saNCrtd2XD3/jrrpChUQ+8k+mCGvQJqQsdy6b4eetEirO8Z5wOQcMG7D8fZqsNs6Nx6Vq/XmLP7AL+k2uEbNEKZgNve7UyMGS1CHno1SYaoTtB7AMRGuM5ubUuNve4QQn8yAGqOERSOU2RJoVSrn46KKqNUUyg70OG10I/4QgBVwMR0u+z9Zca0EtjPsghZwSM3vakwTQDXeuITTuFPvIzbf0zwFE8A+VvpQtNoHfX7MMMLyE35U5Bs4dbe/6uWDR2hVn2jkznxAiSkJ5TQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBHGabeYjzZF45Lwfd99LElMGxQIdKz8e90xOJOueTLxIVep6xK6f9/Ihpryb/zUa25UJYkNZs2+C93/0WFjXGTl/OnTQuRg2hJlXeecF5wJl8lK51SwzIhLFY/dAI7O37y/Pma/joyGOJRlYfvCQAYBB3rYMgtw8P3FtzO90jIg8oT2dMPdh4P4XoqxNH1GIXMctKdnVN4ffIyEBoim+Zm0OzUnFLHWH0fC2L1uWP/U3QR/aos+PrZyLL0DponYSnHzrRKKRknSFMltEjOwFXKk/RtJfeEbvvfMPek7GRS2+fTsr2rAQ7CAKbjf494OSHSv/O7MjzgSH/Ad1rKyAqe"
],
"x5t": "k7pDpVT5uy06kSn_iDr3UXvZvzk",
"x5t#S256": "fTH7sgLmz6Xg9SO_Msq0HqtAP5_OdywYB29AVmIK6R8"
},
{
"kid": "ubqhyrrx9PSPYTFZ7heXgY_BI-JUvNoWpAJVHt8PuM0",
"kty": "RSA",
"alg": "RS256",
"use": "sig",
"n": "5p_BrUbjQ09gH2DxfEyKbfmIC464F1pjaYhUt_fEHXy_9cxkgIiTp7YSmLbH3gxx7yLnpH0UKj6PLFjVuqPi7zAcQKxLeTgpOuhVvl4u72nP-xep36U5eu7_OLpZSAr2Fx_1dIs6HkFBDrFyEdcCjLGsLRcN5elCuBQ2ZXTqK0LSk5J-CF_WctExPbuHLBnTgkbNYSdRCebXHvVmAQZwevb8TGTRwolnsrRPZqDvL1bVjbkF7IR2ieo2RuO_ipVvIwWM1WgSj4YCTMf4BX2GkNOmMLASZDNU1vfqP_nqsLPsnWALYYvmPRkdnOWkRGm5aRuE2iSF7vqkyBS_qISQXw",
"e": "AQAB",
"x5c": [
"MIICnzCCAYcCBgGWiVSGezANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDDAhzc29fdGVzdDAeFw0yNTA1MDEwMDUwNDBaFw0zNTA1MDEwMDUyMjBaMBMxETAPBgNVBAMMCHNzb190ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5p/BrUbjQ09gH2DxfEyKbfmIC464F1pjaYhUt/fEHXy/9cxkgIiTp7YSmLbH3gxx7yLnpH0UKj6PLFjVuqPi7zAcQKxLeTgpOuhVvl4u72nP+xep36U5eu7/OLpZSAr2Fx/1dIs6HkFBDrFyEdcCjLGsLRcN5elCuBQ2ZXTqK0LSk5J+CF/WctExPbuHLBnTgkbNYSdRCebXHvVmAQZwevb8TGTRwolnsrRPZqDvL1bVjbkF7IR2ieo2RuO/ipVvIwWM1WgSj4YCTMf4BX2GkNOmMLASZDNU1vfqP/nqsLPsnWALYYvmPRkdnOWkRGm5aRuE2iSF7vqkyBS/qISQXwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCbb7Pmn2Efpq7XcQrX5fGG3nA5b+jzgHm4EDR+qP6r5VE+rGKMJ3HLfh++vCZ8Q5o9OS3DDQ78LPlRQtHOLj/O/5Oyyx/goz0Qwm7McT1rhY0lIfmxfnOl4ywcAB3bypwxJVJW0h062hqEk4mxF3UVDT7ANGoYMLp1jyoOJH3/ahEmEsaiaqQzuIidlWfA0/1d8KFigg77w/Mz/87eH9DVnPhhnPkxF92I1bvEdjfqwskl5LhrCP5mXPMdjJ3TkfTcbN47V8sqKuW7lG54Cjnu2CmzlJBW194mwsfL+bv61VEsrN8+8CewV8sDB26epX5wsoP/SPd3GVQetdB5SPow"
],
"x5t": "EMs6gwvSF4SkwR0dVvNFY5I9Gj0",
"x5t#S256": "__KqFnFLxby4SfFDmv5J6zvpbE6v-M_7jWO9kdDjf3s"
}
]
}
```
However when deploying Confluent Platform yml I get the following,
```yaml
kafka-1 kafka org.apache.kafka.common.KafkaException: org.apache.kafka.common.KafkaException: The OAuth validator configuration encountered an error when initializing the VerificationKeyResolver
kafka-1 kafka at org.apache.kafka.common.network.SaslChannelBuilder.configure(SaslChannelBuilder.java:218)
kafka-1 kafka at org.apache.kafka.common.network.ChannelBuilders.create(ChannelBuilders.java:300)
kafka-1 kafka at org.apache.kafka.common.network.ChannelBuilders.serverChannelBuilder(ChannelBuilders.java:197)
kafka-1 kafka at kafka.network.Processor.(SocketServer.scala:1413)
kafka-1 kafka at kafka.network.Acceptor.newProcessor(SocketServer.scala:1259)
kafka-1 kafka at kafka.network.Acceptor.$anonfun$addProcessors$1(SocketServer.scala:1218)
kafka-1 kafka at scala.collection.immutable.Range.foreach$mVc$sp(Range.scala:190)
kafka-1 kafka at kafka.network.Acceptor.addProcessors(SocketServer.scala:1217)
kafka-1 kafka at kafka.network.DataPlaneAcceptor.configure(SocketServer.scala:796)
kafka-1 kafka at kafka.network.SocketServer.createDataPlaneAcceptorAndProcessors(SocketServer.scala:340)
kafka-1 kafka at kafka.network.SocketServer.$anonfun$new$63(SocketServer.scala:261)
kafka-1 kafka at kafka.network.SocketServer.$anonfun$new$63$adapted(SocketServer.scala:261)
kafka-1 kafka at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:619)
kafka-1 kafka at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:617)
kafka-1 kafka at scala.collection.AbstractIterable.foreach(Iterable.scala:935)
kafka-1 kafka at kafka.network.SocketServer.(SocketServer.scala:261)
kafka-1 kafka at kafka.server.BrokerServer.startup(BrokerServer.scala:560)
kafka-1 kafka at kafka.server.KafkaRaftServer.$anonfun$startup$2(KafkaRaftServer.scala:119)
kafka-1 kafka at kafka.server.KafkaRaftServer.$anonfun$startup$2$adapted(KafkaRaftServer.scala:119)
kafka-1 kafka at scala.Option.foreach(Option.scala:437)
kafka-1 kafka at kafka.server.KafkaRaftServer.startup(KafkaRaftServer.scala:119)
kafka-1 kafka at kafka.Kafka$.main(Kafka.scala:112)
kafka-1 kafka at kafka.Kafka.main(Kafka.scala)
kafka-1 kafka Caused by: org.apache.kafka.common.KafkaException: The OAuth validator configuration encountered an error when initializing the VerificationKeyResolver
kafka-1 kafka at org.apache.kafka.common.security.oauthbearer.OAuthBearerValidatorCallbackHandler.init(OAuthBearerValidatorCallbackHandler.java:149)
kafka-1 kafka at org.apache.kafka.common.security.oauthbearer.OAuthBearerValidatorCallbackHandler.configure(OAuthBearerValidatorCallbackHandler.java:139)
kafka-1 kafka at org.apache.kafka.common.network.SaslChannelBuilder.configure(SaslChannelBuilder.java:182)
kafka-1 kafka ... 22 more
kafka-1 kafka Caused by: java.io.IOException: Non 200 status code (403 Forbidden) returned from http://keycloak:8080/realms/sso_test/protocol/openid-connect/certs
kafka-1 kafka at org.jose4j.http.Get.get(Get.java:86)
kafka-1 kafka at org.jose4j.jwk.HttpsJwks.refresh(HttpsJwks.java:204)
kafka-1 kafka at org.jose4j.jwk.HttpsJwks.getJsonWebKeys(HttpsJwks.java:161)
kafka-1 kafka at org.apache.kafka.common.security.oauthbearer.internals.secured.RefreshingHttpsJwks.init(RefreshingHttpsJwks.java:182)
kafka-1 kafka at org.apache.kafka.common.security.oauthbearer.internals.secured.RefreshingHttpsJwksVerificationKeyResolver.init(RefreshingHttpsJwksVerificationKeyResolver.java:104)
kafka-1 kafka at org.apache.kafka.common.security.oauthbearer.OAuthBearerValidatorCallbackHandler$RefCountingVerificationKeyResolver.init(OAuthBearerValidatorCallbackHandler.java:269)
kafka-1 kafka at org.apache.kafka.common.security.oauthbearer.OAuthBearerValidatorCallbackHandler.init(OAuthBearerValidatorCallbackHandler.java:147)
kafka-1 kafka ... 24 more
kafka-1 kafka [INFO] 2025-05-01 06:26:03,081 [kafka-shutdown-hook] org.apache.kafka.common.utils.AppInfoParser unregisterAppInfo - App info kafka.server for 1 unregistered
```
This is the content of my kafka.properties
```properties
authorizer.class.name=io.confluent.kafka.security.authorizer.ConfluentServerAuthorizer
auto.create.topics.enable=false
config.providers=file
config.providers.file.class=org.apache.kafka.common.config.provider.FileConfigProvider
confluent.authorizer.access.rule.providers=KRAFT_ACL,CONFLUENT
confluent.balancer.enable=true
confluent.license.topic.replication.factor=3
confluent.metadata.enable.server.urls.refresh=false
confluent.metadata.server.auth.ssl.principal.mapping.rules=RULE:.*CN=([a-zA-Z0-9.-]*).*$/$1/,DEFAULT
confluent.metadata.server.authentication.method=BEARER
confluent.metadata.server.impersonation.super.users=User:kafka;User:CN=kafka,C=ES,L=Madrid,O=Unidad Editorial SA;User:sr;User:ssologin;User:kafka-broker
confluent.metadata.server.listeners=https://0.0.0.0:8090
confluent.metadata.server.oauthbearer.expected.issuer=http://keycloak:8080/realms/sso_test
confluent.metadata.server.oauthbearer.jwks.endpoint.url=http://keycloak:8080/realms/sso_test/protocol/openid-connect/certs
confluent.metadata.server.oauthbearer.sub.claim.name=client_id
confluent.metadata.server.public.key.path=/mnt/secrets/mds-token/mdsPublicKey.pem
confluent.metadata.server.ssl.client.authentication=REQUIRED
confluent.metadata.server.ssl.key.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
confluent.metadata.server.ssl.keystore.location=/mnt/sslcerts/keystore.p12
confluent.metadata.server.ssl.keystore.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
confluent.metadata.server.ssl.keystore.reload=true
confluent.metadata.server.ssl.truststore.location=/mnt/sslcerts/truststore.p12
confluent.metadata.server.ssl.truststore.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
confluent.metadata.server.sso.mode=oidc
confluent.metadata.server.token.auth.enable=true
confluent.metadata.server.token.key.path=/mnt/secrets/mds-token/mdsTokenKeyPair.pem
confluent.metadata.server.token.max.lifetime.ms=3600000
confluent.metadata.server.token.signature.algorithm=RS256
confluent.metadata.server.user.store=OAUTH
confluent.metrics.reporter.bootstrap.servers=kafka.confluent.svc.cluster.local:9071
confluent.metrics.reporter.publish.ms=30000
confluent.metrics.reporter.security.protocol=SSL
confluent.metrics.reporter.ssl.key.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
confluent.metrics.reporter.ssl.keystore.location=/mnt/sslcerts/keystore.p12
confluent.metrics.reporter.ssl.keystore.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
confluent.metrics.reporter.ssl.truststore.location=/mnt/sslcerts/truststore.p12
confluent.metrics.reporter.ssl.truststore.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
confluent.oauth.groups.claim.name=groups
confluent.oidc.idp.authorize.base.endpoint.uri=http://keycloak:8080/realms/sso_test/protocol/openid-connect/auth
confluent.oidc.idp.client.id=${file:/mnt/secrets/oidccredential/oidcClientSecret.txt:clientId}
confluent.oidc.idp.client.secret=${file:/mnt/secrets/oidccredential/oidcClientSecret.txt:clientSecret}
confluent.oidc.idp.groups.claim.name=profile_groups
confluent.oidc.idp.issuer=http://keycloak:8080/realms/sso_test
confluent.oidc.idp.jwks.endpoint.uri=http://keycloak:8080/realms/sso_test/protocol/openid-connect/certs
confluent.oidc.idp.refresh.token.enabled=false
confluent.oidc.idp.sub.claim.name=sub
confluent.oidc.idp.token.base.endpoint.uri=http://keycloak:8080/realms/sso_test/protocol/openid-connect/token
confluent.oidc.session.max.timeout.ms=21600000
confluent.oidc.session.token.expiry.ms=90000
confluent.operator.managed=true
controller.listener.names=CONTROLLER
controller.quorum.voters=9990@kraftcontroller-0.kraftcontroller.confluent.svc.cluster.local:9074,9991@kraftcontroller-1.kraftcontroller.confluent.svc.cluster.local:9074,9992@kraftcontroller-2.kraftcontroller.confluent.svc.cluster.local:9074
default.replication.factor=3
delete.topic.enable=true
group.max.session.timeout.ms=1200000
inter.broker.listener.name=REPLICATION
inter.broker.protocol.version=3.4
kafka.rest.auth.ssl.principal.mapping.rules=RULE:.*CN=([a-zA-Z0-9.-]*).*$/$1/,DEFAULT
kafka.rest.bootstrap.servers=kafka.confluent.svc.cluster.local:9073
kafka.rest.client.sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required clientId="${file:/mnt/secrets/oauth-jass/oauth.txt:clientId}" clientSecret="${file:/mnt/secrets/oauth-jass/oauth.txt:clientSecret}";
kafka.rest.client.sasl.mechanism=OAUTHBEARER
kafka.rest.client.sasl.oauthbearer.token.endpoint.url=http://keycloak:8080/realms/sso_test/protocol/openid-connect/token
kafka.rest.client.security.protocol=SASL_SSL
kafka.rest.client.ssl.key.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
kafka.rest.client.ssl.keystore.location=/mnt/sslcerts/keystore.p12
kafka.rest.client.ssl.keystore.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
kafka.rest.client.ssl.truststore.location=/mnt/sslcerts/truststore.p12
kafka.rest.client.ssl.truststore.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
kafka.rest.confluent.metadata.bootstrap.server.urls=https://kafka.confluent.svc.cluster.local:8090
kafka.rest.confluent.metadata.enable.server.urls.refresh=false
kafka.rest.confluent.metadata.http.auth.credentials.provider=OAUTHBEARER
kafka.rest.confluent.metadata.oauthbearer.login.client.id=${file:/mnt/secrets/oauth-jass/oauth.txt:clientId}
kafka.rest.confluent.metadata.oauthbearer.login.client.secret=${file:/mnt/secrets/oauth-jass/oauth.txt:clientSecret}
kafka.rest.confluent.metadata.oauthbearer.token.endpoint.url=http://keycloak:8080/realms/sso_test/protocol/openid-connect/token
kafka.rest.confluent.metadata.ssl.key.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
kafka.rest.confluent.metadata.ssl.keystore.location=/mnt/sslcerts/keystore.p12
kafka.rest.confluent.metadata.ssl.keystore.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
kafka.rest.confluent.metadata.ssl.truststore.location=/mnt/sslcerts/truststore.p12
kafka.rest.confluent.metadata.ssl.truststore.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
kafka.rest.enable=true
kafka.rest.kafka.rest.resource.extension.class=io.confluent.kafkarest.security.KafkaRestSecurityResourceExtension
kafka.rest.oauthbearer.expected.issuer=http://keycloak:8080/realms/sso_test
kafka.rest.oauthbearer.jwks.endpoint.url=http://keycloak:8080/realms/sso_test/protocol/openid-connect/certs
kafka.rest.oauthbearer.sub.claim.name=client_id
kafka.rest.public.key.path=/mnt/secrets/mds-token/mdsPublicKey.pem
kafka.rest.rest.servlet.initializor.classes=io.confluent.common.security.jetty.initializer.AuthenticationHandler
kafka.rest.ssl.client.authentication=REQUIRED
listener.name.controller.oauthbearer.sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required clientId="ssologin" clientSecret="W8V4cqewCy54x4gm7UjhLkk0rrFDi6DT" refresh_ms="3000" ssl.truststore.location="/mnt/sslcerts/truststore.jks" ssl.truststore.password="mystorepassword" unsecuredLoginStringClaim_sub="thePrincipalName";
listener.name.controller.ssl.client.auth=required
listener.name.controller.ssl.key.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
listener.name.controller.ssl.keystore.location=/mnt/sslcerts/keystore.p12
listener.name.controller.ssl.keystore.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
listener.name.controller.ssl.truststore.location=/mnt/sslcerts/truststore.p12
listener.name.controller.ssl.truststore.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
listener.name.external.oauthbearer.sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required unsecuredLoginStringClaim_sub="thePrincipalName";
listener.name.external.oauthbearer.sasl.server.callback.handler.class=org.apache.kafka.common.security.oauthbearer.secured.OAuthBearerValidatorCallbackHandler
listener.name.external.principal.builder.class=io.confluent.kafka.security.authenticator.OAuthKafkaPrincipalBuilder
listener.name.external.sasl.enabled.mechanisms=OAUTHBEARER
listener.name.external.sasl.mechanism=OAUTHBEARER
listener.name.external.sasl.oauthbearer.jwks.endpoint.url=http://keycloak:8080/realms/sso_test/protocol/openid-connect/certs
listener.name.external.ssl.client.auth=required
listener.name.external.ssl.key.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
listener.name.external.ssl.keystore.location=/mnt/sslcerts/keystore.p12
listener.name.external.ssl.keystore.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
listener.name.external.ssl.principal.mapping.rules=RULE:.*CN=([a-zA-Z0-9.-]*).*$/$1/,DEFAULT
listener.name.external.ssl.truststore.location=/mnt/sslcerts/truststore.p12
listener.name.external.ssl.truststore.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
listener.name.internal.ssl.client.auth=required
listener.name.internal.ssl.key.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
listener.name.internal.ssl.keystore.location=/mnt/sslcerts/keystore.p12
listener.name.internal.ssl.keystore.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
listener.name.internal.ssl.principal.mapping.rules=RULE:.*CN=([a-zA-Z0-9.-]*).*$/$1/,DEFAULT
listener.name.internal.ssl.truststore.location=/mnt/sslcerts/truststore.p12
listener.name.internal.ssl.truststore.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
listener.name.replication.ssl.client.auth=required
listener.name.replication.ssl.key.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
listener.name.replication.ssl.keystore.location=/mnt/sslcerts/keystore.p12
listener.name.replication.ssl.keystore.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
listener.name.replication.ssl.principal.mapping.rules=RULE:.*CN=([a-zA-Z0-9.-]*).*$/$1/,DEFAULT
listener.name.replication.ssl.truststore.location=/mnt/sslcerts/truststore.p12
listener.name.replication.ssl.truststore.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
listener.name.token.oauthbearer.sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required unsecuredLoginStringClaim_sub="thePrincipalName" publicKeyPath="/mnt/secrets/mds-token/mdsPublicKey.pem";
listener.name.token.oauthbearer.sasl.server.callback.handler.class=io.confluent.kafka.server.plugins.auth.token.CompositeBearerValidatorCallbackHandler
listener.name.token.principal.builder.class=io.confluent.kafka.security.authenticator.OAuthKafkaPrincipalBuilder
listener.name.token.sasl.enabled.mechanisms=OAUTHBEARER
listener.name.token.sasl.mechanism=OAUTHBEARER
listener.name.token.sasl.oauthbearer.expected.issuer=http://keycloak:8080/realms/sso_test
listener.name.token.sasl.oauthbearer.jwks.endpoint.url=http://keycloak:8080/realms/sso_test/protocol/openid-connect/certs
listener.name.token.sasl.oauthbearer.sub.claim.name=client_id
listener.name.token.ssl.key.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
listener.name.token.ssl.keystore.location=/mnt/sslcerts/keystore.p12
listener.name.token.ssl.keystore.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
listener.name.token.ssl.truststore.location=/mnt/sslcerts/truststore.p12
listener.name.token.ssl.truststore.password=${file:/mnt/sslcerts/jksPassword.txt:jksPassword}
listener.security.protocol.map=CONTROLLER:SSL,EXTERNAL:SASL_SSL,INTERNAL:SSL,REPLICATION:SSL,TOKEN:SASL_SSL
listeners=EXTERNAL://:9092,INTERNAL://:9071,REPLICATION://:9072,TOKEN://:9073
log.dirs=/mnt/data/data0/logs
log.message.format.version=3.4
log.retention.check.interval.ms=300000
log.retention.hours=168
log.segment.bytes=1073741824
metric.reporters=io.confluent.metrics.reporter.ConfluentMetricsReporter
min.insync.replicas=2
num.io.threads=8
num.network.threads=4
num.partitions=1
num.recovery.threads.per.data.dir=1
offsets.commit.timeout.ms=15000
offsets.retention.minutes=10080
offsets.topic.compression.codec=3
offsets.topic.replication.factor=3
process.roles=broker
replica.lag.time.max.ms=45000
socket.receive.buffer.bytes=102400
socket.request.max.bytes=104857600
socket.send.buffer.bytes=102400
ssl.enabled.protocols=TLSv1.2
super.users=User:kafka;User:ssologin
transaction.state.log.min.isr=2
transaction.state.log.replication.factor=3
```
This is the full yaml
```yaml
apiVersion: platform.confluent.io/v1beta1
kind: KRaftController
metadata:
name: kraftcontroller
namespace: confluent
spec:
configOverrides:
server:
- listener.name.controller.oauthbearer.sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required clientId="ssologin" clientSecret="W8V4cqewCy54x4gm7UjhLkk0rrFDi6DT" refresh_ms="3000" ssl.truststore.location="/mnt/sslcerts/truststore.jks" ssl.truststore.password="mystorepassword" unsecuredLoginStringClaim_sub="thePrincipalName";
replicas: 3
dataVolumeCapacity: 10Gi
image:
application: confluentinc/cp-server:7.9.0
init: confluentinc/confluent-init-container:2.11.0
listeners:
controller:
authentication:
type: mtls
principalMappingRules:
- "RULE:.*CN=([a-zA-Z0-9.-]*).*$/$1/"
- "DEFAULT"
tls:
enabled: true
authorization:
type: rbac
superUsers:
- User:kafka
- User:ssologin
dependencies:
mdsKafkaCluster:
bootstrapEndpoint: kafka.confluent.svc.cluster.local:9071
authentication:
type: mtls
sslClientAuthentication: true
tls:
enabled: true
tls:
secretRef: tls-kafka
---
apiVersion: platform.confluent.io/v1beta1
kind: Kafka
metadata:
name: kafka
namespace: confluent
spec:
configOverrides:
server:
- listener.name.controller.oauthbearer.sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required clientId="ssologin" clientSecret="W8V4cqewCy54x4gm7UjhLkk0rrFDi6DT" refresh_ms="3000" ssl.truststore.location="/mnt/sslcerts/truststore.jks" ssl.truststore.password="mystorepassword" unsecuredLoginStringClaim_sub="thePrincipalName";
authorization:
type: rbac
superUsers:
- User:kafka
- User:ssologin
replicas: 3
image:
application: confluentinc/cp-server:7.9.0
init: confluentinc/confluent-init-container:2.11.0
dataVolumeCapacity: 10Gi
tls:
secretRef: tls-kafka
listeners:
internal:
authentication:
type: mtls
mtls:
sslClientAuthentication: "required"
principalMappingRules:
- "RULE:.*CN=([a-zA-Z0-9.-]*).*$/$1/"
- "DEFAULT"
tls:
enabled: true
external:
authentication:
type: oauth
jaasConfig:
secretRef: oauth-jass
oauthSettings:
groupsClaimName: groups
jwksEndpointUri: http://keycloak:8080/realms/sso_test/protocol/openid-connect/certs
tokenEndpointUri: http://keycloak:8080/realms/sso_test/protocol/openid-connect/token
expectedIssuer: http://keycloak:8080/realms/sso_test # Añadido
# validatorCallbackHandler: io.confluent.kafka.server.plugins.auth.ConfluentOAuthBearerValidatorCallbackHandler # Añadido
mtls:
sslClientAuthentication: "required"
principalMappingRules:
- "RULE:.*CN=([a-zA-Z0-9.-]*).*$/$1/"
- "DEFAULT"
tls:
enabled: true
externalAccess:
type: loadBalancer
loadBalancer:
domain: $INGRESS_IP.nip.io
brokerPrefix: b
bootstrapPrefix: kafka
metricReporter:
enabled: true
authentication:
type: mtls
tls:
enabled: true
services:
kafkaRest:
authentication:
type: oauth
oauth:
secretRef: oauth-jass
configuration:
tokenEndpointUri: http://keycloak:8080/realms/sso_test/protocol/openid-connect/token
expectedIssuer: http://keycloak:8080/realms/sso_test
jwksEndpointUri: http://keycloak:8080/realms/sso_test/protocol/openid-connect/certs
subClaimName: client_id
mtls:
sslClientAuthentication: "required"
principalMappingRules:
- RULE:^CN=([a-zA-Z0-9]*).*$/$1/
- DEFAULT
mds:
impersonation:
admins:
- User:kafka
- User:CN=kafka,C=ES,L=Madrid,O=Unidad Editorial SA
- User:ssologin
tls:
enabled: true
tokenKeyPair:
secretRef: mds-token
provider:
mtls:
sslClientAuthentication: "required"
principalMappingRules: [ "RULE:.*CN=([a-zA-Z0-9.-]*).*$/$1/,DEFAULT" ]
oauth:
configurations:
expectedIssuer: http://keycloak:8080/realms/sso_test
jwksEndpointUri: http://keycloak:8080/realms/sso_test/protocol/openid-connect/certs
subClaimName: client_id
oidc:
clientCredentials:
secretRef: oidccredential
configurations:
groupsClaimName: profile_groups
subClaimName: sub
issuer: http://keycloak:8080/realms/sso_test # Cambiado de localhost a keycloak
jwksEndpointUri: http://keycloak:8080/realms/sso_test/protocol/openid-connect/certs
authorizeBaseEndpointUri: http://keycloak:8080/realms/sso_test/protocol/openid-connect/auth # Cambiado
tokenBaseEndpointUri: http://keycloak:8080/realms/sso_test/protocol/openid-connect/token
refreshToken: false
dependencies:
kafkaRest:
authentication:
type: oauth
jaasConfig:
secretRef: oauth-jass
oauthSettings:
tokenEndpointUri: http://keycloak:8080/realms/sso_test/protocol/openid-connect/token
expectedIssuer: http://keycloak:8080/realms/sso_test
jwksEndpointUri: http://keycloak:8080/realms/sso_test/protocol/openid-connect/certs
subClaimName: client_id
sslClientAuthentication: true
tls:
enabled: true
secretRef: tls-kafka
kRaftController:
controllerListener:
tls:
enabled: true
authentication:
type: mtls
clusterRef:
name: kraftcontroller
---
apiVersion: platform.confluent.io/v1beta1
kind: ControlCenter
metadata:
name: controlcenter
namespace: confluent
spec:
# configOverrides:
# server:
# - listener.name.controller.oauthbearer.sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required clientId="${file:/mnt/secrets/oauth-jass/oauth.txt:clientId}" clientSecret="${file:/mnt/secrets/oauth-jass/oauth.txt:clientSecret}" refresh_ms="3000" ssl.truststore.location="/mnt/sslcerts/truststore.jks" ssl.truststore.password="mystorepassword" unsecuredLoginStringClaim_sub="thePrincipalName";
configOverrides:
server:
- listener.name.controller.oauthbearer.sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required clientId="ssologin" clientSecret="W8V4cqewCy54x4gm7UjhLkk0rrFDi6DT" refresh_ms="3000" ssl.truststore.location="/mnt/sslcerts/truststore.jks" ssl.truststore.password="mystorepassword" unsecuredLoginStringClaim_sub="thePrincipalName";
authorization:
type: rbac
replicas: 1
podTemplate:
probe:
liveness:
periodSeconds: 10
failureThreshold: 5
timeoutSeconds: 500
image:
application: confluentinc/cp-enterprise-control-center:7.9.0
init: confluentinc/confluent-init-container:2.11.0
dataVolumeCapacity: 10Gi
tls:
secretRef: tls-controlcenter
dependencies:
kafka:
bootstrapEndpoint: kafka.confluent.svc.cluster.local:9071
authentication:
type: mtls
tls:
enabled: true
mds:
ssoProtocol: oidc
endpoint: https://kafka.confluent.svc.cluster.local:8090
tokenKeyPair:
secretRef: mds-token
authentication:
type: mtls
sslClientAuthentication: true
tls:
enabled: true
---
apiVersion: platform.confluent.io/v1beta1
kind: SchemaRegistry
metadata:
name: schemaregistry
namespace: confluent
spec:
configOverrides:
server:
- listener.name.controller.oauthbearer.sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required clientId="ssologin" clientSecret="W8V4cqewCy54x4gm7UjhLkk0rrFDi6DT" refresh_ms="3000" ssl.truststore.location="/mnt/sslcerts/truststore.jks" ssl.truststore.password="mystorepassword" unsecuredLoginStringClaim_sub="thePrincipalName";
authorization:
type: rbac
replicas: 1
image:
application: confluentinc/cp-schema-registry:7.9.0
init: confluentinc/confluent-init-container:2.11.0
tls:
secretRef: tls-schemaregistry
authentication:
type: oauth
oauth:
secretRef: oauth-jass
configuration:
tokenEndpointUri: http://keycloak:8080/realms/sso_test/protocol/openid-connect/token
expectedIssuer: http://keycloak:8080/realms/sso_test
jwksEndpointUri: http://keycloak:8080/realms/sso_test/protocol/openid-connect/certs
subClaimName: client_id
mtls:
sslClientAuthentication: "required"
externalAccess:
type: loadBalancer
loadBalancer:
domain: $INGRESS_IP.nip.io
prefix: schemaregistry
dependencies:
kafka:
bootstrapEndpoint: kafka.confluent.svc.cluster.local:9071
authentication:
type: mtls
tls:
enabled: true
mds:
ssoProtocol: oidc
endpoint: https://kafka.confluent.svc.cluster.local:8090
tokenKeyPair:
secretRef: mds-token
authentication:
type: mtls
sslClientAuthentication: true
tls:
enabled: true
---
apiVersion: platform.confluent.io/v1beta1
kind: KafkaRestClass
metadata:
name: default
namespace: confluent
spec:
# configOverrides:
# server:
# - listener.name.controller.oauthbearer.sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required clientId="${file:/mnt/secrets/oauth-jass/oauth.txt:clientId}" clientSecret="${file:/mnt/secrets/oauth-jass/oauth.txt:clientSecret}" refresh_ms="3000" ssl.truststore.location="/mnt/sslcerts/truststore.jks" ssl.truststore.password="mystorepassword" unsecuredLoginStringClaim_sub="thePrincipalName";
kafkaClusterRef:
name: kafka
namespace: confluent
kafkaRest:
endpoint: https://kafka.confluent.svc.cluster.local:8090
authentication:
type: oauth
oauth:
secretRef: oauth-jass
configuration:
tokenEndpointUri: http://keycloak:8080/realms/sso_test/protocol/openid-connect/token
expectedIssuer: http://keycloak:8080/realms/sso_test # Añadido
sslClientAuthentication: true
tls:
secretRef: tls-kafka
---
apiVersion: platform.confluent.io/v1beta1
kind: Connect
metadata:
name: connect
namespace: confluent
spec:
configOverrides:
server:
- listener.name.controller.oauthbearer.sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required clientId="ssologin" clientSecret="W8V4cqewCy54x4gm7UjhLkk0rrFDi6DT" refresh_ms="3000" ssl.truststore.location="/mnt/sslcerts/truststore.jks" ssl.truststore.password="mystorepassword" unsecuredLoginStringClaim_sub="thePrincipalName";
authorization:
type: rbac
replicas: 1
image:
application: confluentinc/cp-server-connect:7.9.0
init: confluentinc/confluent-init-container:2.11.0
tls:
secretRef: tls-connect
authentication:
type: oauth
oauth:
secretRef: oauth-jass
configuration:
tokenEndpointUri: http://keycloak:8080/realms/sso_test/protocol/openid-connect/token
expectedIssuer: http://keycloak:8080/realms/sso_test
jwksEndpointUri: http://keycloak:8080/realms/sso_test/protocol/openid-connect/certs
subClaimName: client_id
mtls:
sslClientAuthentication: "required"
externalAccess:
type: loadBalancer
loadBalancer:
domain: $INGRESS_IP.nip.io
prefix: connect
dependencies:
kafka:
bootstrapEndpoint: kafka.confluent.svc.cluster.local:9071
authentication:
type: mtls
tls:
enabled: true
mds:
ssoProtocol: oidc
endpoint: https://kafka.confluent.svc.cluster.local:8090
tokenKeyPair:
secretRef: mds-token
authentication:
type: mtls
sslClientAuthentication: true
tls:
enabled: true
```
Is there something missing?
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the security/mtls-rbac-with-sso-oauth example and the supplied kafka.properties, then compare the configured JWKS endpoint with the curl request and the broker's 403 stack trace. Done means the Confluent Platform deployment initializes successfully and the broker can retrieve the Keycloak verification keys.
Written by the indexing model from the issue text.
Assessment
- Domain
- authentication, backend, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100