---
title: Self-signed certificates
url: https://www.tines.com/stories/docs/self-hosted/configuring-tines/self-signed-certificates/
updated: 2026-10-26T22:26:54+00:00
---

*[tines.com](https://www.tines.com/llms.txt) › [Docs](https://www.tines.com/stories/docs/llms.txt) › [Self-Hosted](https://www.tines.com/llm/stories/docs/self-hosted.md) › [Configuring Tines](https://www.tines.com/llm/stories/docs/self-hosted/configuring-tines.md)*

# Self-signed certificates

*[View on tines.com](https://www.tines.com/stories/docs/self-hosted/configuring-tines/self-signed-certificates/)*

Tines uses one certificate so browsers can open your tenant, and a separate set of trusted certificates when a story, a case webhook, or a sign-in flow connects to another server. Trusting a certificate in the browser does not make stories trust it.

Issue the browser certificate for the hostname in `DOMAIN`. Put that hostname in the Common Name and in a subject alternative name. A self-signed certificate is enough for a lab. For production, use a certificate from a certificate authority (CA) that browsers and the rest of your network already trust.

Where you attach that certificate depends on where TLS terminates:

- [Docker Compose](https://www.tines.com/docs/self-hosted/deploying-tines/docker-compose/tines-docker-compose-installation-guide/) presents `tines.crt` and `tines.key` from Nginx.
- [AWS Fargate](https://www.tines.com/docs/self-hosted/deploying-tines/aws-fargate/deployment-guide/) presents an AWS Certificate Manager certificate from the load balancer.
- [Helm](https://www.tines.com/docs/self-hosted/getting-started/helm-charts/) presents a certificate from Nginx, from your ingress or cloud load balancer, or from an OpenShift route.
- [SSL/TLS termination](https://www.tines.com/docs/self-hosted/configuring-tines/ssltls-termination/) covers presenting a certificate directly from `tines-app`.

A public CA at the load balancer means other systems that trust public CAs can call your tenant without extra configuration. A self-signed or private certificate has to be trusted by each outbound connection below.

## Which connection needs which certificate

| Connection | What must trust the server certificate | Where to add it |
| --- | --- | --- |
| Browsers opening Tines | The browser or device | The certificate on Nginx, the load balancer, or `tines-app`, using the deployment guide for your platform. |
| HTTP Request, IMAP, and gRPC actions | `tines-sidekiq`, through a [custom certificate authority](https://www.tines.com/docs/admin/custom-certificate-authority/) | Settings > Custom Cert Authorities. Actions use the authority named in `custom_certificate_authority_name`, which defaults to `default`. |
| Case webhook notifications | `tines-sidekiq`, through the custom certificate authority named `default` | Settings > Custom Cert Authorities, on the authority named `default`. A named authority is not used. |
| A story calling this Tines API, or a case webhook calling a webhook action on this tenant | `tines-sidekiq`, through the `default` custom certificate authority | Add the public certificate served for `DOMAIN` when that certificate is self-signed or private. The hostname in the URL must match the certificate. |
| Single sign-on, including an internal provider such as Keycloak | The operating-system trust store in `tines-app` | Provide your CA bundle to `tines-app`. Custom certificate authorities are not used. |
| LDAP | The LDAP configuration | The CA certificate field on the LDAP page. See [LDAP authentication](https://www.tines.com/docs/self-hosted/configuring-tines/ldap-authentication/). |
| SMTP | The SMTP connection | `SMTP_OPENSSL_CA_FILE`, `SMTP_OPENSSL_CA_PATH`, and `SMTP_OPENSSL_VERIFY_MODE`. See the [environment variable reference](https://www.tines.com/docs/self-hosted/configuring-tines/environment-variable-reference/). |
| Postgres or Redis over TLS | The process that opens that connection | `PGSSLROOTCERT` and `PGSSLMODE`, or the Redis Sentinel TLS variables, in the environment. |
| Run Script, and package installs in `tines-command-runner` | `tines-command-runner` | That container's own trust store. See [Run Script](https://www.tines.com/docs/self-hosted/configuring-tines/run-script-tines-command-runner/). |
| Traffic through a tunnel | The custom certificate authority on the tenant | Settings > Custom Cert Authorities. Leave the tunnel container's certificate files unchanged. |

AI providers can use a custom certificate authority when they connect to a private service. Mutual TLS, where Tines presents a client certificate, is a credential setting and does not change which CA Tines trusts.



## Trust a certificate for stories

Export the PEM-encoded certificate. For a private CA, use the CA certificate that signed the server. For a self-signed server, use that server certificate. Include intermediate certificates in order after the leaf certificate when the server's chain needs them.

Open Settings > Custom Cert Authorities, or https://<tenant-domain>/settings/custom_ca.

Paste the PEM into the authority named default and save. To trust several unrelated servers from every story and from case webhooks, paste each PEM certificate into that same authority, one after another.

Create a named authority when one HTTP Request, IMAP, or gRPC action should trust a different CA. Set custom_certificate_authority_name on that action. Case webhook notifications keep using default.

The authority is stored for the tenant and is added to the public authorities already in the container. Saving it takes effect on the next run, on Docker Compose, AWS Fargate, and Kubernetes. You do not restart tines-sidekiq or mount a file for this path.



An HTTP Request action that fails with certificate verify failed and mentions disable_ssl_verification does not trust the server certificate. Add the CA, then leave disable_ssl_verification unset. Turning verification off accepts any certificate for that action.



## Let stories call this Tines tenant

Case webhook notifications often post to a webhook action on the same tenant, and stories often call the Tines API at https://<DOMAIN>. Both are outbound HTTPS requests from tines-sidekiq to whatever certificate your deployment presents for that hostname.



When that certificate comes from a public CA, such as the AWS Certificate Manager certificate on an AWS Fargate load balancer, tines-sidekiq already trusts it. When it is self-signed or issued by a private CA, add the public certificate to the custom certificate authority named default.



The hostname in the action or webhook URL must match the certificate name. A certificate issued for a different name fails verification even after it is trusted. Browsers still warn about a self-signed certificate until each user trusts it, or until you replace it with a certificate those browsers already trust.



## Trust a certificate for single sign-on

Single sign-on runs in tines-app and uses that container's trust store. A custom certificate authority has no effect on it.



Build a CA bundle that contains the public authorities and your private CA, and provide that file in every tines-app container at /etc/ssl/certs/ca-certificates.crt. Provide the bundle, rather than a single certificate file. That path replaces the bundle shipped in the image, so it needs the public authorities as well as your CA.



On a Linux host you can add the CA and then use the resulting bundle:



Ubuntu or Debian: copy the .crt file to /usr/local/share/ca-certificates/ and run update-ca-certificates. The bundle is /etc/ssl/certs/ca-certificates.crt.

RHEL, CentOS, or Fedora: copy the file to /etc/pki/ca-trust/source/anchors/ and run update-ca-trust extract. The bundle is /etc/pki/tls/certs/ca-bundle.crt.

Deliver that bundle with the same mechanism you use for other files on the platform: a read-only volume on Docker Compose, a secret or config map mounted onto the tines-app pods on Kubernetes, or a file in the [AWS Fargate](https://www.tines.com/docs/self-hosted/deploying-tines/aws-fargate/deployment-guide/) task. Restart tines-app after the file changes. The file stays in place when you upgrade the Tines image.



Story actions and case webhooks still use Custom Cert Authorities, so tines-sidekiq does not need this file for those connections.



## TLS inspection proxies

A proxy that re-signs HTTPS presents its own CA. Trust that CA in the same place as the connection it intercepts:

- Stories and case webhooks: add the proxy CA as a custom certificate authority.
- Single sign-on: add the proxy CA to the tines-app bundle.

Set HTTP_PROXY and HTTPS_PROXY on the containers that should use the proxy. Set NO_PROXY for the database, Redis, and other internal hosts that should connect directly. Those variables are in the [environment variable reference](https://www.tines.com/docs/self-hosted/configuring-tines/environment-variable-reference/).



## Certificate errors


| Error | What to change |
| --- | --- |
| `self-signed certificate` or `unable to get local issuer certificate` | Trust the CA on the connection in the table above. For a private CA, paste the CA certificate. Include missing intermediates in the PEM. |
| `hostname does not match` | Issue the certificate for the hostname in the URL, including a subject alternative name. |
| `certificate has expired` or `certificate is not yet valid` | Replace the certificate. Check that the host clock is correct when a new certificate is reported as not yet valid. |
| Verification succeeds only with `disable_ssl_verification` set | Add the CA, then turn verification back on. |
