I have a GKE architecture with the following components:
External Traffic Flow:
*.example.com
) routes to:
app.example.com
, api.example.com
, idp.example.com
*.k8s.internal.example
) forwards to a Gateway (Gateway API).HTTPRoute
resources (hostnames include both public and internal domains).Keycloak (IDP) Setup:
ClusterIP
service (idp-custom-service:8443
).Spring Boot API (simeox-api):
issuer-uri: https://idp.example.com/realms/my-realm
.Error Observed:
The API fails to validate JWT tokens, throwing:
org.springframework.security.oauth2.jwt.JwtDecoderInitializationException:
Caused by: SSLHandshakeException: PKIX path building failed: unable to find valid certification path
The root cause is the API cannot retrieve Keycloak's OIDC configuration from https://idp.example.com/realms/my-realm/.well-known/openid-configuration
due to certificate trust issues.
Investigation:
idp.example.com
.*.k8s.internal.example
) is likely not trusted by the API’s JVM, but the public F5 certificate (*.example.com
) is publicly trusted.Questions:
How should TLS be configured end-to-end to ensure the API pod trusts Keycloak’s certificate when the internal LB terminates TLS with a different certificate?
Keycloak Certificate Setup:
Relevant Configuration Snippets:
# HTTPRoute for IDP
spec:
hostnames:
- idp.example.com
rules:
- backendRefs:
- name: idp-custom-service
port: 8443
# Keycloak Service
spec:
ports:
- name: https
port: 8443
targetPort: 8443
Additional Context:
spring-boot-starter-oauth2-resource-server
.Secondary Question (Optional):
When deploying Keycloak, why is it necessary to provide a certificate with a private key if TLS is terminated at the load balancer? Shouldn’t the LB handle SSL offloading? Does Keycloak require HTTPS even for internal communication between the LB and pods?
To resolve the issue, I added the Gandi certificate of the F5 load balancer to the backend API if the certificate is publicly signed by Gandi. Initially, I thought it should have been the gateway certificate or the Keycloak certificate, but it turned out that the F5 certificate was actually the one needed.