---
title: TLS certificates
description: Why OpenLM Platform needs a valid, trusted certificate for sign-in to work, how to choose one, and how to use a private CA.
product: OpenLM Platform
---

## Why sign-in needs a valid certificate

Sign-in in OpenLM Platform works only with a valid, trusted certificate, because **the OpenLM Platform services are clients of its web address too**. On most websites a certificate only protects the browser connection. In OpenLM Platform it does more.

When a user opens a screen, the request carries a sign-in token. The service that receives it checks the token by calling `https://<DOMAIN>/identity`, the same public address the browser used. That call is an ordinary HTTPS connection from a pod, and the pod checks the certificate the same way a browser does:

```text
 browser ──https──► ingress ──► service ──https──► ingress ──► identity
                     ▲                              ▲
                certificate                    same certificate,
              checked by the browser         checked by the service
```

So the certificate has to be valid **for the browser and for the pods**:

| If the certificate is… | Browsers | Pods | Result |
|---|---|---|---|
| From a public CA, for `DOMAIN`, not expired | trust it | trust it | Works |
| Self-signed, or from a private CA, root not provided | warning page | reject it | **Home page loads, then every screen fails** |
| For a different name, or expired | warning page | reject it | Same |
| From a private CA, full chain including root provided | trust it (if the root is on users' machines) | trust it | Works |

Unlike a person in a browser, the services can't ignore a certificate warning. If a certificate is wrong, sign-in breaks for everyone.

## Choose a certificate

Pick one of these certificate sources:

- **Recommended, a certificate from a public CA**: For example from DigiCert, Sectigo, or Let's Encrypt, for exactly `DOMAIN` or a wildcard that covers it. Pods trust public CAs by default, so you have nothing more to do.
- **Also fine, your company's private CA**: Users' machines usually trust it already. The pods don't, so you give them the CA, as [Make the pods trust a private CA](#make-the-pods-trust-a-private-ca) describes.
- **Not suitable, self-signed certificates**: Use them only on a short-lived test system, with the steps in [Make the pods trust a private CA](#make-the-pods-trust-a-private-ca), treating the self-signed certificate as its own root.

## Prepare the certificate file

You create the secret `openlm-lb-cert` from two files in [step 3.3](https://www.openlm.com/documentation/cloud/deployment-operations/on-premise/deployment-guide/kubernetes/install/step-3-secrets#33-add-the-tls-certificate):

- **Certificate file** (`fullchain.pem`): PEM, in this order: the server certificate for `DOMAIN`, then each intermediate certificate, and, **for a private CA only**, the root certificate last.
- **Key file** (`privkey.pem`): PEM, not password-protected.

Check the file before you use it:

```bash
openssl crl2pkcs7 -nocrl -certfile "$TLS_CERT_FILE" | openssl pkcs7 -print_certs -noout | grep subject
openssl x509 -in "$TLS_CERT_FILE" -noout -subject -ext subjectAltName -enddate
```

Read the output of the two commands this way:

- The first command lists every certificate in the file, server certificate first.
- The second must show `DOMAIN` under `Subject Alternative Name` and a `notAfter` date in the future.

## Make the pods trust a private CA

The pods run on standard Linux base images that trust the public CAs. For a private CA they need your root certificate as well. The chart can mount a CA bundle into each service (`deploymentCerts` in each component). The exact settings depend on the release, and OpenLM gives them to you together with your release. If you don't have those settings yet, use a certificate from a public CA: it works without them.

:::warning[Include the root]
With a private CA, the most common mistake is a certificate file that has the server certificate and intermediates but not the **root**. Browsers on company machines work (they have the root), so everything looks fine, but services fail with SSL or `IdentityUnavailable` errors. Add the root to the end of the file and recreate the secret.
:::

## Renew the certificate

To renew the certificate, replace the secret, and restart the ingress controller if it doesn't pick up changes by itself. Certificates expire, and when one does, sign-in stops working. Replace the secret:

```bash
kubectl -n openlm create secret tls openlm-lb-cert --cert=fullchain.pem --key=privkey.pem \
  --dry-run=client -o yaml | kubectl -n openlm apply -f -
```

Put the expiry date in your calendar, or let cert-manager renew it for you. A cert-manager `Certificate` that writes into the secret `openlm-lb-cert` works with no change to the platform.

## On OpenShift

The OpenShift router terminates Routes and uses its own certificate unless the Route carries one. See [Red Hat OpenShift: certificates](https://www.openlm.com/documentation/cloud/deployment-operations/on-premise/deployment-guide/kubernetes/platforms/openshift#certificates).
