Skip to main content
Star OpenZiti on GitHub Star
Version: Latest

Step 1: Give the controller a public certificate

The controller highlighted, presenting a public certificate on its client API.

JWT enrollment needs no public certificate. The controller signs the enrollment token, and the token itself is the trust, so the controller can run on its own private PKI (public key infrastructure). See the five-part series on bootstrapping trust for how that works.

Add by URL has no token, so it has nothing to bootstrap trust from. The tunneler must trust the controller enough to download its network JWT, so the URL it downloads from must present a valid certificate the operating system trusts. That certificate comes from a public CA such as Let's Encrypt, or from an enterprise CA your mobile device management (MDM) tool put in the OS trust store. Users are part of that trust too: give them the URL to enter, and tell them not to enter any other.

Configure the controller​

Follow Add a public certificate. Pick any two names you like. The lab uses these examples throughout, so swap in your own names wherever they appear:

NameExampleCertificate
Publicctrl.example.comA Let's Encrypt wildcard for *.example.com
Privatectrl-pki.example.comThe controller's private PKI

Done when​

The first check proves devices trust the public name. The second proves no public root went into the controller's ca bundle. Every enrolled client trusts that bundle, so it must hold only your private PKI. Add a public certificate explains why.

  • The browser opens https://ctrl.example.com:1280 with no certificate warning

  • The controller's CA bundle lists only the private PKI:

    curl -s https://ctrl.example.com:1280/.well-known/est/cacerts \
    | base64 -d | openssl pkcs7 -inform DER -print_certs | grep subject=