Node.js SDK enrollment fails with TLS handshake error — Let's Encrypt + Internal PKI separation

Hi,

I'm deploying OpenZiti with Docker Compose using openziti/ziti-controller and openziti/ziti-router (non-quickstart images). I'm using the Node.js SDK (@openziti/ziti-sdk-nodejs) in an Electron app to enroll a client identity.

Setup:

  • Port 1280 and 8443 open externally

  • Port 6262 is internal Docker only

  • Two DNS names to avoid SAN overlap (as recommended):

    • ziti.certiv.pt → CNAME to server → used for internal PKI/ctrl channel

    • rede.certiv.pt → A record → used for Let's Encrypt / Edge API

docker-compose.yml:

services:
  ziti-controller:
    image: openziti/ziti-controller:latest
    environment:
      - ZITI_HOME=/ziti-controller
      - ZITI_BOOTSTRAP=true
      - ZITI_BOOTSTRAP_PKI=true
      - ZITI_BOOTSTRAP_CONFIG=true
      - ZITI_BOOTSTRAP_DATABASE=true
    ports:
      - "1280:1280"
      - "6262:6262"
    networks:
      ziti-net:
        aliases:
          - ziti-controller
          - ziti.certiv.pt

  ziti-router:
    image: openziti/ziti-router:latest
    environment:
      - ZITI_CTRL_ADVERTISED_ADDRESS=ziti.certiv.pt
      - ZITI_CTRL_ADVERTISED_PORT=6262
      - ZITI_ROUTER_ADVERTISED_ADDRESS=rede.certiv.pt
      - ZITI_ROUTER_PORT=8443
    ports:
      - "8443:8443"

Relevant config.yml sections:

ctrl:
  options:
    advertiseAddress: tls:ziti.certiv.pt:6262
  listener: tls:0.0.0.0:6262

edge:
  api:
    address: rede.certiv.pt:1280

web:
  - name: client-management
    bindPoints:
      - interface: 0.0.0.0:1280
        address: rede.certiv.pt:1280
    identity:
      alt_server_certs:
        - server_cert: "/etc/letsencrypt/live/rede.certiv.pt/fullchain.pem"
          server_key:  "/etc/letsencrypt/live/rede.certiv.pt/privkey.pem"

Problem:

When I try to enroll using the Node.js SDK, the enrollment fails with a TLS error. The controller logs show:

ERR _context=tls:0.0.0.0:1280 

error=remote error: tls: unknown certificate

msg=handshake failed

The browser also shows NET::ERR_CERT_AUTHORITY_INVALID when accessing https://rede.certiv.pt:1280/zac, which suggests the alt_server_certs with Let's Encrypt is not being picked up correctly.

Questions:

  1. Is the alt_server_certs being ignored because the FQDN rede.certiv.pt overlaps with the PKI somehow?

  2. Should the ctrl.options.advertiseAddress use port 6262 (which is internal only) or 1280?

  3. What does the ctrls field in the enrollment JWT contain for client identities, and does the Node.js SDK actually connect to that address after enrollment?

Thank you!