SSL Certificate Configuration¶
This guide explains how to configure OpenLiberty to work with self-signed SSL certificates, which is essential when connecting to Keycloak instances using custom Certificate Authorities (CA).
Why is This Needed?¶
When Keycloak uses self-signed certificates or certificates issued by a custom CA (like a home lab CA), OpenLiberty cannot validate the certificate chain by default. This causes errors when:
- Fetching JWKS (JSON Web Key Set) from Keycloak
- Validating JWT tokens
- Making any HTTPS requests to Keycloak
Common error:
Understanding the Certificate Chain¶
A typical certificate chain looks like this:
Root CA (HomeLab CA Root CA)
↓
Intermediate CA (Home Lab Intermediate)
↓
Server Certificate (keycloak.lab.home)
OpenLiberty needs to trust the entire chain to validate the server certificate.
Prerequisites¶
- OpenLiberty installed
- Access to your CA certificates (root and intermediate)
- Keycloak running with self-signed certificates
Solution Overview¶
We need to:
- Export CA certificates from Keycloak
- Import CA certificates into OpenLiberty's truststore
- Configure OpenLiberty to use the truststore
- Verify the configuration
Step 1: Export CA Certificates¶
If you have access to the Keycloak server:
- Navigate to Keycloak in your browser
- Click the padlock icon in the address bar
- View certificate details
- Export each certificate in the chain:
- Server certificate
- Intermediate CA certificate
- Root CA certificate
- Save as PEM format (
.crtor.pemfiles)
Step 2: Verify Certificate Chain¶
Before importing, verify the certificate chain is complete:
# Check root CA
openssl x509 -in certs/root_ca.crt -noout -subject -issuer
# Check intermediate CA
openssl x509 -in certs/intermediate_ca.crt -noout -subject -issuer
# Verify the chain
openssl verify -CAfile certs/root_ca.crt certs/intermediate_ca.crt
Expected output:
Step 3: Import Certificates into Truststore¶
This assumes you have a separate RootCA certificate, and intermediate certificate and a server certificate chain, adjust as needed. OpenLiberty uses a PKCS12 keystore located at:
Import Root CA Certificate¶
keytool -import \
-alias homelab-root-ca \
-file certs/root_ca.crt \
-keystore API_server/target/liberty/wlp/usr/servers/authTestServer/resources/security/key.p12 \
-storepass changeit \
-noprompt
Import Intermediate CA Certificate¶
keytool -import \
-alias homelab-intermediate-ca \
-file certs/intermediate_ca.crt \
-keystore API_server/target/liberty/wlp/usr/servers/authTestServer/resources/security/key.p12 \
-storepass changeit \
-noprompt
Verify Imports¶
List all certificates in the keystore:
keytool -list \
-keystore API_server/target/liberty/wlp/usr/servers/authTestServer/resources/security/key.p12 \
-storepass changeit
Expected output:
Keystore type: PKCS12
Keystore provider: SUN
Your keystore contains 8 entries
default, 28 Jan 2026, PrivateKeyEntry
homelab-root-ca, 28 Jan 2026, trustedCertEntry
homelab-intermediate-ca, 28 Jan 2026, trustedCertEntry
...
Step 4: Configure OpenLiberty¶
Update server.xml¶
Configure SSL settings in API_server/src/main/liberty/config/server.xml:
<!-- SSL Configuration for JWT/JWKS endpoint -->
<ssl id="jwtSSLConfig"
keyStoreRef="defaultKeyStore"
trustDefaultCerts="true"
verifyHostname="false"
sslProtocol="TLSv1.2"
clientAuthentication="false"
clientAuthenticationSupported="false"/>
<!-- Outbound SSL configuration for REST clients -->
<sslDefault outboundSSLRef="jwtSSLConfig"/>
<!-- Keystore configuration -->
<keyStore id="defaultKeyStore"
password="changeit"/>
<!-- MicroProfile JWT Configuration -->
<mpJwt id="jwtConfig"
jwksUri="${env.JWT_JWKS_URI}"
issuer="${env.JWT_ISSUER}"
audiences="authentication-test-api"
groupNameAttribute="groups"
userNameAttribute="preferred_username"
sslRef="jwtSSLConfig"/>
Key Configuration Options¶
trustDefaultCerts="true"- Trust system default certificatesverifyHostname="false"- Disable hostname verification (development only)sslProtocol="TLSv1.2"- Use TLS 1.2 or highersslRef="jwtSSLConfig"- Reference SSL configuration in mpJwt
Production Settings
For production, set verifyHostname="true" and ensure certificates have correct hostnames.
Optional: JVM Options for Development¶
For development environments, you can add JVM options to disable strict SSL validation:
Create API_server/src/main/liberty/config/jvm.options:
# Disable strict SSL validation (DEVELOPMENT ONLY)
-Dcom.ibm.jsse2.overrideDefaultTLS=true
-Djavax.net.ssl.trustAll=true
-Djdk.internal.httpclient.disableHostnameVerification=true
# Memory settings
-Xmx512m
-Xms256m
Security Warning
Never use these JVM options in production! They disable SSL certificate validation entirely.
Step 5: Restart OpenLiberty¶
After importing certificates and updating configuration:
Or for a full restart:
Step 6: Verify Configuration¶
Test JWKS Endpoint Access¶
Check if OpenLiberty can now access the Keycloak JWKS endpoint:
# Check server logs for SSL errors
tail -f API_server/target/liberty/wlp/usr/servers/authTestServer/logs/messages.log | grep -i "ssl\|pkix\|certificate"
Success indicators: - No PKIX errors - No SSL handshake failures - JWT tokens validate successfully
Test API with JWT Token¶
# Get token from Keycloak
TOKEN=$(curl -s -k -X POST https://keycloak.lab.home/realms/secure-test/protocol/openid-connect/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=authentication-test-api" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "grant_type=password" \
-d "username=testuser2" \
-d "password=YOUR_PASSWORD" | jq -r '.access_token')
# Test API
curl -s http://localhost:9080/api/v1/schedule \
-H "Authorization: Bearer $TOKEN" | jq .
Expected result: 200 OK with schedule data (no SSL errors)
Troubleshooting¶
Still Getting PKIX Errors¶
Possible causes:
- Incomplete certificate chain
- Verify you imported both root and intermediate CA certificates
-
Check certificate chain with
openssl verify -
Server not restarted
- Truststore changes require a full server restart
-
Use
cd API_server && mvn liberty:stop && mvn liberty:dev -
Wrong keystore path
- Verify keystore location matches server.xml configuration
- Check file permissions
Certificate Import Failed¶
# Check if certificate is valid
openssl x509 -in certs/root_ca.crt -text -noout
# Verify certificate format (should be PEM)
head -1 certs/root_ca.crt
# Should show: -----BEGIN CERTIFICATE-----
Hostname Verification Errors¶
If you see hostname verification errors:
For production, ensure certificates have correct Subject Alternative Names (SAN).
Automated Certificate Import Script¶
Create a script to automate certificate import:
#!/bin/bash
# import_ca_certs.sh
KEYSTORE="API_server/target/liberty/wlp/usr/servers/authTestServer/resources/security/key.p12"
STOREPASS="changeit"
# Import root CA
keytool -import \
-alias homelab-root-ca \
-file certs/root_ca.crt \
-keystore "$KEYSTORE" \
-storepass "$STOREPASS" \
-noprompt
# Import intermediate CA
keytool -import \
-alias homelab-intermediate-ca \
-file certs/intermediate_ca.crt \
-keystore "$KEYSTORE" \
-storepass "$STOREPASS" \
-noprompt
echo "Certificates imported successfully"
keytool -list -keystore "$KEYSTORE" -storepass "$STOREPASS" | grep -i "homelab"
Make it executable:
Production Considerations¶
Use Proper Certificates¶
For production:
- Use certificates from trusted CA (Let's Encrypt, DigiCert, etc.)
- Enable hostname verification
- Remove JVM SSL bypass options
- Use strong keystore passwords
- Regularly rotate certificates
Certificate Renewal¶
When certificates are renewed:
- Export new certificates
- Remove old certificates from truststore:
- Import new certificates
- Restart server
Monitoring Certificate Expiration¶
Check certificate expiration dates:
# Check certificate validity
openssl x509 -in certs/root_ca.crt -noout -dates
# Check keystore certificates
keytool -list -v \
-keystore target/liberty/wlp/usr/servers/authTestServer/resources/security/key.p12 \
-storepass changeit | grep -A2 "Valid"
Next Steps¶
- Keycloak Setup - Configure Keycloak realm
- Groups Mapper - Configure role mapping
- Troubleshooting - Common issues