- step-cli installed locally
- cert-manager running in target cluster
- [OPTIONAL] Vault accessible by
cert-manager
Monoskope needs it's own PKI because components like the m8 Operator
use mTLS to communicate and authenticate with the Monoskope Control Plane (m8CP)
.
First this document shows how the chain looks like and how it works. After that the manual on how to set up everything is explained.
Good you ask! Certificate chains can really mess with your head. Have a look at the following diagram:
At the root of everything sits our Trust Anchor (TA)
as we call it.
The TA
is a self signed certificate you create and provide to the m8CP
.
Monoskope utilizes cert-manager
and uses it as root CA
based on the TA
you provide.
Now with the CA
in place, we can issue server and client certificates.
Now we come to the part which is not automated.
The TA
will expire based on what you've configured when creating the certificate.
Now what? Let's have a look at the following diagram:
With a buffer of at least 30 days you want to rotate the TA
.
You create a new certificate like you did initially for the TA
.
But now you bundle the old and the new certificate together and make this bundle available to the m8CP
.
Now with the bundle in place certificate chains can have the old or the new TA
as root.
This is not an issue since every chain can still be validated no matter which TA
has been used.
Now this bundle has to stay until every server and client certificate has been rotated. Only after that point it is safe to remove the old TA
from the bundle.
Create a root CA certificate which we call the trust anchor:
step certificate create root.monoskope.cluster.local ca.crt ca.key \
--profile root-ca --no-password --insecure --not-after=87600h
This trust anchor must be made available to cert-manager to let it issue certificates based on that trust anchor.
This can be done in two ways:
- via the CA issuer
- via the Vault issuer
If you're using the CA Issuer you have to set the following in the values.yaml
when deploying Monoskope:
pki:
enabled: true
issuer:
ca:
enabled: true
existingTrustAnchorSecretName: "m8-trust-anchor" # name of secret in K8s where you have to provide the root ca
Create secret containing the generated trust anchor as in the namespace you're about to deploy Monoskope:
kubectl -n monoskope create secret tls m8-trust-anchor --cert=ca.crt --key=ca.key
After storing the trust anchor in a K8s secret you can delete your local copy or store it in a save location.
This part has not been documented yet. Feel free to create a PR/MR.
Rotating the trust anchor without downtime is a multi-step process: you must generate a new trust anchor, bundle it with the old one, rotate all certificates derived from the old one, and finally remove the old trust anchor from the bundle.
Create a new trust anchor:
step certificate create root.monoskope.cluster.local ca-new.crt ca-new.key \
--profile root-ca --no-password --insecure
Create Bundle with old and new CA cert:
step certificate bundle ca-new.crt ca-old.crt bundle.crt