Admin life cycle: from password to long-lived cert

My goal is to improve the security posture of a deployed OpenZiti Controller by using only certificate authentication for administrative operations.

What’s the best way to get a long-lived client cert from the edge signer CA if I have a password, e.g., I am default admin?

  1. client gets short-lived API session cert, admin adds cert authenticator, client extends cert authenticator to get long-lived cert. This works but it is a lot of steps spanning client and mgmt API.

  2. admin adds outstanding cert enrollment for existing admin identity, client performs ott enrollment. This has the advantage of not creating any new identities.

  3. admin creates a new identity with isAdmin: true, client enrolls with JWT. This works and seems to me like it’s the best option to offer because it doesn’t introduce any new concepts and can be accomplished in the console.

1 Like

Option 3 to me sounds logical because you already have a trust element there. If you don’t trust the cert the client has from enrolment then there is a big problem.

That covers off ziti elements. You still need to figure out the heartbeat user - do they have the ability to load up a ssh key(s) against identity and the client upon login uses the ssh key?

Then comes the ZAC?

What about client enrolment cert for ziti components and 2FA for heartbeats using interactive login/ZAC. API already has an authentication scheme.

Option 4: I haven’t done it in a while, but you should be able to directly create a certificate authenticator via the /authenticators endpoint. Then delete the admin updb authenticator.

Some other notes:

Option 1you should never have needed an API Session Certificate. Those are usually only necessary for connecting to Edge Routers.

Option 3, the default admin is protected from being deleted. Creating a separate admin is not protected in the same way.

Option 4 is one of the steps I did for option 1, preceded by obtaining a cert through the API session cert request, which now I take it shouldn’t have been necessary.

Still, it’s not clear how I get a cert for an existing user that has only a password without requesting an API session cert.

How does admin request the cert that’s included in the request to create the cert authenticator? Example request for a cert authenticator:

POST /edge/management/v1/authenticators
{
  "method": "cert",
  "identityId": "q4KhUbRJB",
  "certPem": "-----BEGIN CERTIFICATE-----\nMIICjjCCAjOgAwIBAgIDBBq1MAoGCCqGSM49BAMCMDIxMDAuBgNVBAMTJ3ppdGkt\nY29udHJvbGxlci1jdHJsLXBsYW5lLWludGVybWVkaWF0ZTAeFw0yMzAzMDUxOTQ5\nNTNaFw0yMzAzMDYwNzQ5NTNaMFcxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJOQzES\nMBAGA1UEBxMJQ2hhcmxvdHRlMRMwEQYDVQQKEwpOZXRGb3VuZHJ5MRIwEAYDVQQD\nEwltaW5pYWRtaW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCwOb8p\nthqA7k83kN9wnEOUtyQmWTG5CkaYQCxzbROLp50rqM2K5cVhknI+AZYf5GMGVvjQ\nbFR3XUrt2UoO6nHs7y8tycPP+6ojxKI9pQCiKbTdkJIERuiZlp698OyyO9r+raXM\nHnfPDkC1AMRNZSm3nc0nVagak1IGi/2O6aLspjEnwIRowhbZy7EyI9uZJCpyLUhF\nGmERXD5aHP7o7jrmad9bdcw/njspmh1ThrvFFqNR2u2u+1Y/YdZfUuhO4ljyfhw7\nuPMTZhJkTV7VW61sy8yl2XeEMf2Y0LWMBP8JxZK8ABeIg42PYK1EC6jLFWlbm8wA\nQ/FOxezAhkcx8Qu1AgMBAAGjSDBGMA4GA1UdDwEB/wQEAwIEsDATBgNVHSUEDDAK\nBggrBgEFBQcDAjAfBgNVHSMEGDAWgBSHDYtS6PAoNM6dxM5qpQDBZMrNOzAKBggq\nhkjOPQQDAgNJADBGAiEAyYraw8/sQsoEGkzvUQWpDOiDvGthaW4YRpmT6X8apkQC\nIQD/1PvOD4zGZn8bIT2X02lF4gEes4uYwQBa/HH2QrBpZw==\n-----END CERTIFICATE-----\n\n"
  }
}

Thanks for pointing out the special protection enjoyed by the default admin. I wasn’t aware it couldn’t be deleted.

That lends credibility to option 2: admin uses password to create an outstanding enrollment, then extracts key/cert from identity for future use with mgmt API authenticate operation.

For option 4: You would be creating the certificate yourself by using openssl and the controller’s signing cert/private key. You will need access to the machine the controller is running on with sufficient privileges to access the private key file.

No matter what you do, to create an authenticator for the default admin, you will need to go through a CSR process. That CSR process can be done via:

Option 1) finagling API Session Certs to do the CSR process for you
Option 2) creating an enrollment and consuming it (part of the input is a CSR)
Option 3) creating a new admin
Option 4) creating your own CSR and fulfilling it w/ the controllers signing cert via openssl CLI

Option 2 is the best if you only have remote access. Option 4 is possible if you have access to the controller, but does have a higher level of knowledge requirement via “how to use OpenSSL”.

I was trying to do everything through the edge APIs, but as you pointed out I could bypass the API if I control the edge signer CA.

That might be a good fit for my use case because all the controller’s certs are issued by cert-manager (in Kubernetes) anyway, so it’s one additional resource in the Helm chart to get a client cert for the admin user, and cert-manager will already handle cert renewal. I can mount the cert on the admin container for use by ziti CLI when cert auth is available.

With the cert in hand, all that remains is to create the cert authenticator. I can’t use ziti CLI to create a cert authenticator yet, only updb is supported in 0.27.5, but it’s just the one request shown in the prior threadpost above this one. I suppose a Helm life-cycle hook could do it for the admin container.

This all translates to an automated way of bootstrapping cert auth for the default admin in k8s deployments.