How to rely on a PKI (Public Key Infrastructure) on


Using public key infrastructure (PKI) on your project for authentication.


PKI is used to:

  • centralize the authentication process
  • automatically provide new accounts for authentication
  • avoid a dependency on a centralized authentication server which might not be available at all times
  • automatically expire accounts for authentication after a given period (unless they refresh)

PKI starts with the root certificate authority who keeps a private key and a certificate. The certificate is public, and can be used to verify users’ certificates.

When a new user (automated or not) needs a new certificate, they:

  • generate a private key
  • generate a Certificate Signing Request (CSR) that is sent to the root certificate authority

The root certificate authority receives the CSR, validates that the user is valid, and returns a signed certificate to the user. The user can then use this signed certificate to authenticate.

When a server wants to authenticate a certificate, it uses the root certificate authority’s certificate to verify the signature in the user’s certificate. This verification can be done on, which is what this How-To will show.


You will need:

  • A local git repository that has the project as a git remote
  • A working application setup on the project
  • openssl


1. Create a PKI

Create the certificate authority private key and certificate

Create the private key that the certificate authority must keep private.

$ openssl genrsa -out /tmp/rootCA.key 4096
Generating RSA private key, 4096 bit long modulus

The key will look similar to this:

$ head -n2 /tmp/rootCA.key 

Based on this, create the public certificate:

$ openssl req -x509 -new -nodes -key /tmp/rootCA.key -sha256 -days 365 -out /tmp/rootCA.crt

Pass the previously-created key.

openssl will ask a few questions, they’re not important for the purpose of this How-To.

The public certificate will look similar to this:

$ head -n2 /tmp/rootCA.crt 

Create the first user’s private key and CSR

Now that the certificate authority is setup, create a user’s private key and CSR.

This creates the private key:

$ openssl genrsa -out /tmp/user.key 4096
Generating RSA private key, 4096 bit long modulus

And this creates the CSR:

$ openssl req -new -key /tmp/user.key -out /tmp/user.csr

openssl will ask again some questions that are not important for the purpose of this How-To.

Create the first user’s public certificate

Based on the explanation above, use the root certificate authority’s private key to sign the CSR, which creates a new public certificate for the user.

$ openssl x509 -req -in /tmp/user.csr -CA /tmp/rootCA.crt -CAkey /tmp/rootCA.key \
-CAcreateserial -out /tmp/user.crt -days 30 -sha256

This creates a public certificate that the user can use, valid for 30 days.

Note that only the user can use this certificate to authenticate, because it needs the private key (“user.key” above).

Et voila! We now have a PKI with one user.

2. Authenticate users of the PKI on

We’re now getting to the easy part of this How-To: we’re going to authenticate our user on using TLS client certificates.

For this test, we’re going to need 3 things:

  • The root certificate authority’s public certificate (rootCA.crt above)
  • The user’s private key (user.key above)
  • The user’s public certificate (user.crt above)

The first step is configuring your project to authenticate users by providing the root certificate authority’s public certificate, as such in the .platform/routes.yaml:

    type: upstream
    upstream: app:http
        client_authentication: "require"
            - !include
                type: string
                path: rootCA.crt

Put the rootCA.crt file in the .platform/ folder.

Commit and push these changes:

$ git add .platform/routes.yaml .platform/rootCA.crt
$ git commit -m "Enable TLS client certificates authentication"
$ git push platform master

And that’s it!

Test the changes:

$ curl
curl: (35) error:14094412:SSL routines:ssl3_read_bytes:sslv3 alert bad certificate
$ curl --key user.key --cert user.crt
It's working!


Setting up a project to authenticate users using PKI requires only a few lines of code added to the .platform/routes.yaml file.

1 Like