From 8aef180ccd713e1ef156f9d3ee2c85dd60b2407d Mon Sep 17 00:00:00 2001 From: "Albern S." <62778698+abnsy@users.noreply.github.com> Date: Thu, 20 Nov 2025 11:21:43 +0700 Subject: [PATCH] Improve TLS handling in OpenIDConnectAuthenticator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I’m sending a small security improvement for the OIDC authenticator. When the kubeconfig doesn’t include idp-certificate authority-data the code leaves sslContext as null and falls back to the OS trust store. This can behave differently depending on the environment and isn’t always secure. In this update I added a default SSLContext that always uses the system CA.... If the user provides a custom CA, that one is still loaded and used instead. No behavior change other than making TLS more consistent and safer. Thanks! --- .../OpenIDConnectAuthenticator.java | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/util/src/main/java/io/kubernetes/client/util/authenticators/OpenIDConnectAuthenticator.java b/util/src/main/java/io/kubernetes/client/util/authenticators/OpenIDConnectAuthenticator.java index 6fa79a96a2..4739f44083 100644 --- a/util/src/main/java/io/kubernetes/client/util/authenticators/OpenIDConnectAuthenticator.java +++ b/util/src/main/java/io/kubernetes/client/util/authenticators/OpenIDConnectAuthenticator.java @@ -113,13 +113,27 @@ public Map refresh(Map config) { String clientSecret = (String) config.getOrDefault(OIDC_CLIENT_SECRET, ""); String idpCert = (String) config.get(OIDC_IDP_CERT_DATA); + SSLContext sslContext = null; + // Initialize a secure default SSLContext using the system default TrustManager. + // This ensures that we always have certificate validation even when no idp-certificate-authority-data is provided. + try { + TrustManagerFactory defaultTmf = + TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + defaultTmf.init((KeyStore) null); + SSLContext defaultSslContext = SSLContext.getInstance("TLS"); + defaultSslContext.init(defaultTmf.getTrustManagers(), null, new SecureRandom()); + sslContext = defaultSslContext; + } catch (KeyStoreException | NoSuchAlgorithmException | KeyManagementException e) { + throw new RuntimeException("Unable to initialize default TLS context", e); + } + if (idpCert != null) { - // fist, lets get the pem + // first, let's get the pem (custom CA provided by user) String pemCert = new String(Base64.getDecoder().decode(idpCert)); - // next lets get a cert object + // next let's get a cert object // need an alias name to store the certificate in a keystore. Also // java keystores need passwords. this value is as good as any as // there isn't anything actually secret being stored. @@ -143,10 +157,11 @@ public Map refresh(Map config) { TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX"); tmf.init(ks); - // TODO would be good to make this more dyanamic. Doesn't seem like - // a good way to do this. - sslContext = SSLContext.getInstance("TLSv1.2"); - sslContext.init(null, tmf.getTrustManagers(), new SecureRandom()); + // Use TLSv1.2 for the custom context initialized with the provided CA(s) + SSLContext idpSslContext = SSLContext.getInstance("TLSv1.2"); + idpSslContext.init(null, tmf.getTrustManagers(), new SecureRandom()); + // override sslContext to use the idp-specific SSLContext + sslContext = idpSslContext; } catch (KeyStoreException | NoSuchAlgorithmException @@ -157,6 +172,7 @@ public Map refresh(Map config) { } } + // check the identity provider's configuration url for a token endpoint String tokenURL = loadTokenURL(issuer, sslContext);