Canton High Availability TLS configuration

Hello, team!
I have issue with tls configuration for canton participant version 2.5. We have HA setup for participant. Also we enabled tls configuration for participant ledger-api. We installed it in kubernetes. For participant ledger-api we want expose it outside. For expose we are using kube ingressroute and external domain for ingressroute.
After we created self-signed certificate for internal tls connection and custom certificate for external tls connection.
Self-signed cert:

  commonName: cert-selfsigned
  - "localhost"
  - ""
  - ""

External cert:

  commonName: participant.custom.domain
  - participant.custom.domain

Participant config:

            ledger-api {
                port = 4001
                address =
                tls {
                    cert-chain-file = "./certs/tls.crt" # internal certificate
                    private-key-file = "./certs/tls.key" # internal key
                    trust-collection-file = "./certs/tls.crt" # internal certificate
                    client-auth = {
                        type = require
                        admin-client {
                            cert-chain-file = "./certs/tls.crt" #internal certificate
                            private-key-file = "./certs/tls.key" #internal key
                    minimum-server-protocol-version = TLSv1.3
                    ciphers = null

But when we try connect to participant ledger-api with external url(from ingressroute) we get GRPCTimeout. We know that it related to certificate(can not validate external certs).
If we setup external certificate and key as cert-chain-file and private-key-file, we get issue in participant logs that is not in subject alt name in certificate. Also we can not create external certificate and include there ipAddresses: as SAN.

Are there ways to configure tls for participant that we can have internal tls connection between components and also able connect using external url(external cert) to participant?
Thanks for advise.

Hi @Maksym_Zhovanyk

There is an internal connection that tries to use the Ledger API from the participant node itself. Could you please try adding the to the SANs for the external certificate as the error message states its missing and then try again with that?

Kind Regards,

This solution we already did. Yes, it is working but we want to release it to production in future and this is not allowed according our policies and approaches. We can not include as SANs to external production certificates. Are there other ways fix it? Maybe setup two certificates and two private keys or combine them or etc? Could you please advise?

Why it is a problem to include in the SANs? in this context only means all local interfaces of the verifying machine. The way to circumvent this is to use a different value for the address, but that has to be recognized by the local canton process as one of the interfaces it can bind and then connect to.

We have published an example project using the best practices to follow when securing Canton:

1 Like

so if I correct understand this project: GitHub - digital-asset/ex-secure-canton-infra: Reference deployment of a secure Canton infrastructure (PKI, JWT, HA) you can propose as best practices? And adding as SANs for production certificate setup for canton is way which you confirmed? No other ways in current configuration, I mean if we leave as internal interface for canton processes?
Thanks for advise.

@Maksym_Zhovanyk I think my point about the possibility of using another address value was missed, so let me reiterate. If you do not want to add the into your SANs you have the option to use a different value in the ledger api configuration for address. In this case you need to make sure the following are true:

  • The value used be it a domain or an IP has to translate to an interface which will be visible by the external world when the service binds to it.
  • The process itself also has to be able to resolve and connect to the : there so the participant node can start up properly
  • The value has to present as a Subject Alternative Name in the certificate presented by the Ledger API, so the internal client can verify it sucessfully.

Unrelated to this detail, yes the linked example is our current collection as best practices in the parameter space that it covers.