Skip to main content
Version: 5.1

Configure TLS Certificates

ICP ships with a self-signed certificate. For production, replace it with a certificate issued by your own or a public certificate authority (CA). ICP can serve that certificate directly, so a reverse proxy is optional.

All ICP HTTPS listeners share one keystore, so one change covers every port:

PortUsed byWho connects
9446Console, GraphQL API, WebSocketBrowsers, API clients
9445Runtime listener (heartbeats)MI and BI runtimes
9447Built-in user store auth serviceICP itself
9449OpenSearch adapter serviceICP itself

ICP also calls ports 9447 and 9449 over HTTPS. These internal calls verify the certificate too, so ICP must trust your CA and reach those ports by a host name in the certificate.

Prerequisites
  • The server certificate and its private key, in PEM format.
  • The CA certificates in PEM format: the root CA, and any intermediate CAs.
  • openssl and keytool (included with Java).

Certificate host names​

The certificate's Subject Alternative Names (SANs) must cover every host name that clients use to reach ICP:

  • The external host name of ICP, for example icp.example.com. Browsers and runtimes use this name.
  • localhost. By default, ICP calls its own services at https://localhost:9447 and https://localhost:9449.

If your CA does not issue certificates for localhost, leave it out and point the internal URLs to the external host name instead. See Step 3.

Step 1: Create the keystore​

  1. Create a CA chain file. List the CA that issued the server certificate first and the root CA last. If your CA gave you a bundle in this order, use it instead:

    cat intermediate-ca.crt ca-root.crt > ca-chain.crt

    If the server certificate is issued directly by the root CA, use ca-root.crt as the chain file.

  2. Combine the certificate, its private key, and the CA chain into a PKCS12 keystore. OpenSSL prompts for the keystore password:

    openssl pkcs12 -export \
    -in icp.crt \
    -inkey icp.key \
    -certfile ca-chain.crt \
    -name icp \
    -out <ICP_HOME>/conf/security/icp-keystore.p12
  • Keep only one private key entry in the keystore. ICP has no setting to choose a key alias.
  • The private key password must be the same as the keystore password. openssl pkcs12 -export uses the same password for both.
  • -certfile adds the CA chain, so that clients receive the full chain during the TLS handshake.

Step 2: Add the CA to the ICP truststore​

ICP uses its truststore to verify certificates on its internal HTTPS calls. Import your root CA:

keytool -importcert -noprompt \
-alias corp-root-ca \
-file ca-root.crt \
-keystore <ICP_HOME>/conf/security/client-truststore.jks \
-storepass wso2carbon

The default truststore password is wso2carbon.

Step 3: Configure ICP​

Add the following top-level keys to <ICP_HOME>/conf/deployment.toml, before any [section] header:

keystorePath = "<ICP_HOME>/conf/security/icp-keystore.p12"
keystorePassword = "<keystore-password>"
truststorePath = "<ICP_HOME>/conf/security/client-truststore.jks"
truststorePassword = "wso2carbon"
publicBaseUrl = "https://icp.example.com:9446"

If you use a relative path, it is resolved from <ICP_HOME>/bin, because ICP is started from the bin directory. You can also use an absolute path.

If the certificate does not include localhost, point ICP's calls to its own services at a host name in the certificate. The host name must resolve to the ICP server from the ICP server itself, through DNS or /etc/hosts.

observabilityBackendURL = "https://icp.example.com:9449"
# Built-in user store only. Keep your existing value if authBackendUrl points to a custom backend.
authBackendUrl = "https://icp.example.com:9447"
# LDAP user store only (ldapUserStoreEnabled = true).
ldapAuthBackendUrl = "https://icp.example.com:9450"

Set only the keys for the user store you use. For the available backends, see Authentication Backends.

If authBackendUrl points to a custom authentication backend, ICP verifies that backend's certificate against the ICP truststore, not the ICP server certificate. Import the CA that issued the backend's certificate into the ICP truststore, as in Step 2.

To store the passwords encrypted, see Encrypt Secrets.

Restart ICP. For all keys, see Server Configuration.

Step 4: Configure runtimes to trust the CA​

Each runtime verifies the ICP certificate when it connects to port 9445. The serverUrl or icp_url that the runtime uses must contain a host name that is in the certificate.

Copy the root CA in PEM format to the runtime host, then update the integration's Config.toml:

[wso2.icp.runtime.bridge]
serverUrl = "https://icp.example.com:9445"
enableSSL = true
cert = "/opt/certs/ca-root.crt"

enableSSL is false by default, which means the runtime does not verify the ICP certificate. When enableSSL is true, cert is required: the runtime does not fall back to the JVM's default truststore.

For the other settings, see Connect an Integration to ICP.

Verify the setup​

  1. Check that each port serves your certificate, signed by your CA and valid for the host name. Each port should print Verify return code: 0 (ok):

    for p in 9445 9446 9447 9449; do
    echo "== $p"
    echo | openssl s_client -connect icp.example.com:$p -servername icp.example.com \
    -verify_hostname icp.example.com \
    -CAfile ca-root.crt 2>/dev/null | grep -E "subject=|issuer=|Verify return code"
    done
  2. Sign in to the console at https://icp.example.com:9446. Signing in also tests ICP's internal call to the auth service.

  3. Open Runtimes in the console. Each connected runtime shows the status RUNNING.

Troubleshooting​

SymptomCauseFix
Sign-in fails with Authentication service unavailable, and the ICP log shows SSLHandshakeException for localhost/127.0.0.1:9447ICP does not trust your CAImport the CA into the ICP truststore. See Step 2
Same error, with the CA already in the ICP truststoreThe certificate does not include localhostAdd localhost to the SANs, or set authBackendUrl and observabilityBackendURL. See Step 3
BI runtime stops at startup with Certificate file location must be provided for secure connectionenableSSL is true, but cert is not setSet cert to the CA certificate in PEM format
BI runtime logs Failed to send initial heartbeat with SSLHandshakeExceptionThe serverUrl host name is not in the certificateUse a host name from the certificate's SANs
MI logs PKIX path building failedMI does not trust your CAImport the CA into the MI truststore
MI logs Certificate for <host> doesn't match any of the subject alternative namesThe icp_url host name is not in the certificateUse a host name from the certificate's SANs

What's next​