Certificate Loaders¶
Certificate loaders provide a flexible way to load TLS certificates and keys from various sources and formats. They are used for configuring key-stores (client certificates for mTLS) and trust-stores (CA certificates for server verification).
Overview¶
The certificate loader system supports multiple certificate formats and sources:
| Loader Kind | Component Name | Source | Format | Use Case |
|---|---|---|---|---|
| PKCS12 File Path | pkcs12-file-path |
File path | PKCS12 (.p12, .pfx) | Standard keystore files |
| PKCS12 File Base64 | pkcs12-file-base64 |
Inline | PKCS12 (Base64) | Kubernetes secrets, env vars |
| PKCS7 File Path | pkcs7-file-path |
File path | PKCS7 (.p7b, .p7c) | Certificate bundles/chains |
| PKCS7 File Base64 | pkcs7-file-base64 |
Inline | PKCS7 (Base64) | Certificate bundles in secrets |
| JKS File Path | jks-file-path |
File path | JKS/PKCS12 | Legacy Java keystores |
| JKS File Base64 | jks-file-base64 |
Inline | JKS/PKCS12 (Base64) | Embedded keystores |
| PEM File Path | pem-file-path |
File path | PEM | Standard certs/keys |
| PEM File Base64 | pem-file-base64 |
Inline | PEM (Base64) | Kubernetes secrets |
| PEM File Text | pem-file-text |
Inline | PEM (raw) | Direct PEM content |
| DER File Path | der-file-path |
File path | DER | Binary certificates |
| DER File Base64 | der-file-base64 |
Inline | DER (Base64) | Embedded binary certs |
Configuration Structure¶
Certificate loaders are configured within TLS settings for both key-stores and trust-stores:
# Key-store (client certificate for mTLS)
kete.routes.<NAME>.destination.tls.key-store.loader.kind=<loader-kind>
kete.routes.<NAME>.destination.tls.key-store.loader.<property>=<value>
kete.routes.<NAME>.destination.tls.key-store.password=<password>
# Trust-store (CA certificate for server verification)
kete.routes.<NAME>.destination.tls.trust-store.loader.kind=<loader-kind>
kete.routes.<NAME>.destination.tls.trust-store.loader.<property>=<value>
kete.routes.<NAME>.destination.tls.trust-store.password=<password>
Loader Kinds¶
PKCS12 File Path Loader (pkcs12-file-path)¶
Loads a PKCS12 keystore from a file path. Most common format for client certificates.
Properties:
| Property | Required | Default | Description |
|---|---|---|---|
path |
Yes | - | Absolute path to PKCS12 file |
Example:
kete.routes.secure.destination.tls.key-store.loader.kind=pkcs12-file-path
kete.routes.secure.destination.tls.key-store.loader.path=/opt/keycloak/certs/client.p12
kete.routes.secure.destination.tls.key-store.password=changeit
PKCS12 File Base64 Loader (pkcs12-file-base64)¶
Loads a PKCS12 keystore from Base64-encoded content. Ideal for Kubernetes secrets or environment variables.
Properties:
| Property | Required | Default | Description |
|---|---|---|---|
base64 |
Yes | - | Base64-encoded PKCS12 content |
Example:
kete.routes.secure.destination.tls.key-store.loader.kind=pkcs12-file-base64
kete.routes.secure.destination.tls.key-store.loader.base64=MIIKegIBAzCCCj4GCSqGSIb3...
kete.routes.secure.destination.tls.key-store.password=changeit
Encoding a PKCS12 file:
# Linux/macOS
base64 -w 0 client.p12 > client.p12.b64
# Windows PowerShell
[Convert]::ToBase64String([IO.File]::ReadAllBytes("client.p12")) | Out-File client.p12.b64
JKS File Path Loader (jks-file-path)¶
Loads any Java KeyStore (JKS or PKCS12) from a file path. Auto-detects format.
Properties:
| Property | Required | Default | Description |
|---|---|---|---|
path |
Yes | - | Absolute path to keystore file |
Example:
kete.routes.secure.destination.tls.trust-store.loader.kind=jks-file-path
kete.routes.secure.destination.tls.trust-store.loader.path=/opt/keycloak/certs/truststore.jks
kete.routes.secure.destination.tls.trust-store.password=changeit
JKS File Base64 Loader (jks-file-base64)¶
Loads any Java KeyStore (JKS or PKCS12) from Base64-encoded content.
Properties:
| Property | Required | Default | Description |
|---|---|---|---|
base64 |
Yes | - | Base64-encoded keystore content |
Example:
kete.routes.secure.destination.tls.trust-store.loader.kind=jks-file-base64
kete.routes.secure.destination.tls.trust-store.loader.base64=/u3+7QAAAAIAAAABAAAAAQAFYWxpYXM...
kete.routes.secure.destination.tls.trust-store.password=changeit
PEM File Path Loader (pem-file-path)¶
Loads certificates and/or private keys from a PEM-formatted file. Supports certificate chains and encrypted private keys.
Properties:
| Property | Required | Default | Description |
|---|---|---|---|
path |
Yes | - | Absolute path to PEM file |
Example - CA Certificate:
kete.routes.secure.destination.tls.trust-store.loader.kind=pem-file-path
kete.routes.secure.destination.tls.trust-store.loader.path=/opt/keycloak/certs/ca.pem
Example - Client Certificate + Key:
kete.routes.secure.destination.tls.key-store.loader.kind=pem-file-path
kete.routes.secure.destination.tls.key-store.loader.path=/opt/keycloak/certs/client-combined.pem
kete.routes.secure.destination.tls.key-store.password=keypassword
PEM File Format:
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAJC1...
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAw7...
-----END RSA PRIVATE KEY-----
PEM File Base64 Loader (pem-file-base64)¶
Loads PEM content that has been Base64-encoded. Useful for embedding PEM content in environment variables or secrets.
Properties:
| Property | Required | Default | Description |
|---|---|---|---|
base64 |
Yes | - | Base64-encoded PEM content |
Example:
kete.routes.secure.destination.tls.trust-store.loader.kind=pem-file-base64
kete.routes.secure.destination.tls.trust-store.loader.base64=LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t...
Encoding PEM to Base64:
# Linux/macOS
base64 -w 0 ca.pem > ca.pem.b64
# Windows PowerShell
[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes((Get-Content -Raw ca.pem))) | Out-File ca.pem.b64
PEM File Text Loader (pem-file-text)¶
Loads raw PEM content directly from configuration. Useful for simple setups or testing.
Properties:
| Property | Required | Default | Description |
|---|---|---|---|
text |
Yes | - | Raw PEM content (with newlines escaped) |
Example:
kete.routes.secure.destination.tls.trust-store.loader.kind=pem-file-text
kete.routes.secure.destination.tls.trust-store.loader.text=-----BEGIN CERTIFICATE-----\nMIIDXTCC...kWgAwIB\n-----END CERTIFICATE-----
Note: Newlines in PEM content must be escaped as
\nwhen using environment variables or properties files.
DER File Path Loader (der-file-path)¶
Loads a DER-encoded (binary) X.509 certificate from a file.
Properties:
| Property | Required | Default | Description |
|---|---|---|---|
path |
Yes | - | Absolute path to DER file |
Example:
kete.routes.secure.destination.tls.trust-store.loader.kind=der-file-path
kete.routes.secure.destination.tls.trust-store.loader.path=/opt/keycloak/certs/ca.der
DER File Base64 Loader (der-file-base64)¶
Loads a DER-encoded certificate from Base64-encoded content.
Properties:
| Property | Required | Default | Description |
|---|---|---|---|
base64 |
Yes | - | Base64-encoded DER content |
Example:
kete.routes.secure.destination.tls.trust-store.loader.kind=der-file-base64
kete.routes.secure.destination.tls.trust-store.loader.base64=MIIDXTCCAkWgAwIBAgIJAJC1...
PKCS7 File Path Loader (pkcs7-file-path)¶
Loads certificates from a PKCS#7 file (.p7b, .p7c). PKCS#7 is a certificate-only format commonly used for certificate chains and bundles. It cannot contain private keys, so this loader is only suitable for trust-stores.
Properties:
| Property | Required | Default | Description |
|---|---|---|---|
path |
Yes | - | Absolute path to PKCS#7 file |
Example:
kete.routes.secure.destination.tls.trust-store.loader.kind=pkcs7-file-path
kete.routes.secure.destination.tls.trust-store.loader.path=/opt/keycloak/certs/ca-chain.p7b
Note: PKCS#7 files can contain multiple certificates. Aliases are auto-generated from each certificate's Common Name (CN). If no CN is found, the alias is derived from the certificate's serial number.
PKCS7 File Base64 Loader (pkcs7-file-base64)¶
Loads certificates from Base64-encoded PKCS#7 content. Ideal for Kubernetes secrets or environment variables containing certificate bundles.
Properties:
| Property | Required | Default | Description |
|---|---|---|---|
base64 |
Yes | - | Base64-encoded PKCS#7 content |
Example:
kete.routes.secure.destination.tls.trust-store.loader.kind=pkcs7-file-base64
kete.routes.secure.destination.tls.trust-store.loader.base64=MIIHGgYJKoZIhvcNAQcCoIIHCz...
Note: Aliases are auto-generated from each certificate's Common Name (CN). If no CN is found, the alias is derived from the certificate's serial number (e.g.,
cert-1a2b3c).
Encoding a PKCS#7 file:
# Linux/macOS
base64 -w 0 ca-chain.p7b > ca-chain.p7b.b64
# Windows PowerShell
[Convert]::ToBase64String([IO.File]::ReadAllBytes("ca-chain.p7b")) | Out-File ca-chain.p7b.b64
Note: PKCS#7 cannot contain private keys. Use PKCS#12 or PEM formats for client certificates (key-stores).
Complete Examples¶
Example 1: mTLS with PKCS12 Files¶
Standard mutual TLS using file-based keystores:
kete.routes.mtls-api.destination.kind=http
kete.routes.mtls-api.destination.host=secure-api.example.com
kete.routes.mtls-api.destination.port=443
kete.routes.mtls-api.destination.tls.enabled=true
# Client certificate (key-store)
kete.routes.mtls-api.destination.tls.key-store.loader.kind=pkcs12-file-path
kete.routes.mtls-api.destination.tls.key-store.loader.path=/opt/keycloak/certs/client.p12
kete.routes.mtls-api.destination.tls.key-store.password=clientpass
# CA certificate (trust-store)
kete.routes.mtls-api.destination.tls.trust-store.loader.kind=pkcs12-file-path
kete.routes.mtls-api.destination.tls.trust-store.loader.path=/opt/keycloak/certs/truststore.p12
kete.routes.mtls-api.destination.tls.trust-store.password=trustpass
Example 2: Kubernetes with Base64 Secrets¶
Containerized deployment using Base64-encoded certificates:
apiVersion: v1
kind: Secret
metadata:
name: tls-certs
type: Opaque
stringData:
client-cert: "MIIKegIBAzCCCj4GCSqGSIb3..." # Base64 PKCS12
ca-cert: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..." # Base64 PEM
apiVersion: v1
kind: ConfigMap
metadata:
name: events-config
data:
kete.routes.secure.destination.tls.enabled: "true"
kete.routes.secure.destination.tls.key-store.loader.kind: "pkcs12-file-base64"
kete.routes.secure.destination.tls.trust-store.loader.kind: "pem-file-base64"
# Pod spec referencing secrets
env:
- name: kete.routes.secure.destination.tls.key-store.loader.base64
valueFrom:
secretKeyRef:
name: tls-certs
key: client-cert
- name: kete.routes.secure.destination.tls.key-store.password
valueFrom:
secretKeyRef:
name: tls-certs
key: client-cert-password
- name: kete.routes.secure.destination.tls.trust-store.loader.base64
valueFrom:
secretKeyRef:
name: tls-certs
key: ca-cert
Example 3: PEM Files for Let's Encrypt¶
Using Let's Encrypt certificates in PEM format:
kete.routes.letsencrypt.destination.kind=http
kete.routes.letsencrypt.destination.host=api.example.com
kete.routes.letsencrypt.destination.tls.enabled=true
# Server CA verification
kete.routes.letsencrypt.destination.tls.trust-store.loader.kind=pem-file-path
kete.routes.letsencrypt.destination.tls.trust-store.loader.path=/etc/ssl/certs/ca-certificates.crt
Example 4: Mixed Formats¶
Combining different loader kinds for key-store and trust-store:
kete.routes.mixed.destination.kind=http
kete.routes.mixed.destination.host=api.internal.company.com
kete.routes.mixed.destination.tls.enabled=true
# Client cert from PKCS12 file
kete.routes.mixed.destination.tls.key-store.loader.kind=pkcs12-file-path
kete.routes.mixed.destination.tls.key-store.loader.path=/certs/client.p12
kete.routes.mixed.destination.tls.key-store.password=clientpass
# CA from PEM Base64 (injected from secret)
kete.routes.mixed.destination.tls.trust-store.loader.kind=pem-file-base64
kete.routes.mixed.destination.tls.trust-store.loader.base64=${CA_CERT_BASE64}
Choosing the Right Loader¶
| Scenario | Recommended Loader | Notes |
|---|---|---|
| File-based deployment | pkcs12-file-path, pem-file-path |
Simple, familiar to ops teams |
| Kubernetes secrets | pkcs12-file-base64, pem-file-base64 |
No file mounts needed |
| Environment variables | *-file-base64 variants |
Portable, no file system dependencies |
| Let's Encrypt / PEM certs | pem-file-path, pem-file-base64 |
Native format, no conversion |
| Legacy Java keystores | jks-file-path, jks-file-base64 |
JKS and PKCS12 auto-detection |
| Binary DER certificates | der-file-path, der-file-base64 |
Raw X.509 format |
| Certificate bundles/chains | pkcs7-file-path, pkcs7-file-base64 |
Trust-store only (no keys) |
| Windows/IIS CA exports | pkcs7-file-path, pkcs7-file-base64 |
Common in enterprise environments |
| Testing/development | pem-file-text |
Quick inline configuration |
Certificate Conversion Commands¶
PEM to PKCS12¶
openssl pkcs12 -export \
-in client.pem \
-inkey client-key.pem \
-out client.p12 \
-name "client-cert" \
-password pass:changeit
PKCS12 to PEM¶
# Extract certificate
openssl pkcs12 -in client.p12 -clcerts -nokeys -out client.pem
# Extract private key
openssl pkcs12 -in client.p12 -nocerts -nodes -out client-key.pem
DER to PEM¶
PEM to DER¶
Troubleshooting¶
Common Issues¶
| Error | Cause | Solution |
|---|---|---|
path is required |
Missing path property |
Add loader.path=/path/to/cert |
base64 is required |
Missing base64 property |
Add loader.base64=... |
text is required |
Missing text property |
Add loader.text=-----BEGIN... |
Password verification failed |
Wrong keystore password | Verify key-store.password value |
Certificate parsing error |
Wrong loader kind for format | Match loader kind to certificate format |
Debugging¶
Enable debug logging to troubleshoot keystore loading:
# Use standard Quarkus logging configuration
quarkus.log.category."io.github.fortunen.kete".level=DEBUG
Check the Keycloak server log for detailed TLS initialization messages.