From 04ac16451f5a679a9920cf8876ac891c28dcff51 Mon Sep 17 00:00:00 2001 From: Lucie Milan Date: Wed, 17 Jun 2026 11:11:38 +0200 Subject: [PATCH 1/7] how-to draft --- ...-manager-for-control-plane-certificates.md | 185 ++++++++++++++++++ app/_includes/prereqs/cert-manager.md | 12 ++ 2 files changed, 197 insertions(+) create mode 100644 app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md create mode 100644 app/_includes/prereqs/cert-manager.md diff --git a/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md b/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md new file mode 100644 index 0000000000..1451da7e9e --- /dev/null +++ b/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md @@ -0,0 +1,185 @@ +--- +title: Use cert-manager for control plane certificates +description: Learn how to use cert-manager to provision and rotate TLS certificates for the Kong Mesh control plane on Kubernetes. +content_type: how_to +permalink: /mesh/use-cert-manager-for-control-plane-certificates/ +products: + - mesh +works_on: + - on-prem +breadcrumbs: + - /mesh/ +tags: + - cert-manager + - certificates + - security +tldr: + q: How do I use cert-manager to manage control plane TLS certificates? + a: Create a self-signed `ClusterIssuer`, a CA `Certificate`, a CA-backed `Issuer`, and a control plane `Certificate` in the `kong-mesh-system` namespace, then set `controlPlane.tls.general.secretName` in your Helm values to point to the generated secret. +prereqs: + inline: + - title: Helm + include_content: prereqs/helm + - title: A running Kubernetes cluster + include_content: prereqs/kubernetes/mesh-cluster + - title: Install cert-manager + include_content: prereqs/cert-manager +cleanup: + inline: + - title: Clean up {{site.mesh_product_name}} + include_content: cleanup/products/mesh +related_resources: + - text: Deploy Mesh on Kubernetes + url: /mesh/deploy-mesh-on-kubernetes/ + - text: Deploy Mesh (self-managed) + url: /mesh/deploy-mesh-self-managed/ +--- + +By default, {{site.mesh_product_name}} generates its own self-signed control plane certificates at startup. Using cert-manager lets you manage the full certificate lifecycle — issuance, rotation, and expiry — outside of the control plane itself. This guide walks you through creating the required cert-manager resources and configuring {{site.mesh_product_name}} to use them. + +## Create a self-signed ClusterIssuer + +A `ClusterIssuer` is a cluster-scoped resource that cert-manager uses to sign certificates. Create a self-signed one as the root of your certificate chain: + +```sh +echo "apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: selfsigned-issuer +spec: + selfSigned: {}" | kubectl apply -f - +``` + +## Create the CA certificate + +Use the `selfsigned-issuer` to create a CA certificate in the `kong-mesh-system` namespace. This certificate acts as the root CA that signs the control plane certificate: + +```sh +echo "apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: kong-mesh-selfsigned-ca + namespace: kong-mesh-system +spec: + isCA: true + commonName: kong-mesh-selfsigned-ca + secretName: root-secret + privateKey: + algorithm: ECDSA + size: 256 + issuerRef: + name: selfsigned-issuer + kind: ClusterIssuer + group: cert-manager.io" | kubectl apply -f - +``` + +cert-manager stores the CA certificate and key in a secret named `root-secret` in the `kong-mesh-system` namespace. + +## Create the CA-backed Issuer + +Create a namespace-scoped `Issuer` in `kong-mesh-system` that uses the CA secret to sign certificates: + +```sh +echo "apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: kong-mesh-issuer + namespace: kong-mesh-system +spec: + ca: + secretName: root-secret" | kubectl apply -f - +``` + +## Create the control plane certificate + +Create a `Certificate` resource that cert-manager uses to issue and renew the control plane TLS certificate. The `dnsNames` must include all the DNS names that data planes use to reach the control plane: + +```sh +echo "apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: control-plane-cert + namespace: kong-mesh-system +spec: + secretName: control-plane-cert + duration: 2160h # 90d + renewBefore: 360h # 15d + isCA: false + privateKey: + algorithm: RSA + encoding: PKCS1 + size: 2048 + usages: + - server auth + dnsNames: + - kong-mesh-control-plane.kong-mesh-system.svc + - kong-mesh-control-plane + - kong-mesh-control-plane.kong-mesh-system + - kong-mesh-control-plane.kong-mesh-system.svc.local + issuerRef: + name: kong-mesh-issuer + kind: Issuer" | kubectl apply -f - +``` + +Wait for the certificate to be issued: + +```sh +kubectl wait -n kong-mesh-system --for=condition=ready certificate/control-plane-cert --timeout=60s +``` + +## Install Kong Mesh with the cert-manager certificate + +Install {{site.mesh_product_name}} and point the control plane TLS configuration at the secret cert-manager created: + +```sh +helm repo add kong-mesh https://kong.github.io/kong-mesh-charts +helm repo update +helm upgrade --install \ + --create-namespace \ + --namespace kong-mesh-system \ + kong-mesh kong-mesh/kong-mesh \ + --set controlPlane.tls.general.secretName=control-plane-cert +kubectl wait -n kong-mesh-system --for=condition=ready pod --selector=app=kong-mesh-control-plane --timeout=90s +``` + +If {{site.mesh_product_name}} is already installed, run `helm upgrade` instead of `helm install` with the same `--set` flag. + +## Validate + +Verify that the control plane is running and using the cert-manager-issued certificate: + +1. Confirm the control plane pod is healthy: + + ```sh + kubectl get pods -n kong-mesh-system + ``` + + The `kong-mesh-control-plane` pod should show `Running` in the `STATUS` column. + {:.no-copy-code} + +1. Inspect the certificate the control plane is serving: + + ```sh + kubectl exec -n kong-mesh-system deploy/kong-mesh-control-plane -- \ + openssl s_client -connect localhost:5678 -showcerts /dev/null | \ + openssl x509 -noout -subject -issuer -dates + ``` + + The output should show `kong-mesh-selfsigned-ca` as the issuer and an expiry date 90 days from issuance: + + ```text + subject=CN=kong-mesh-control-plane.kong-mesh-system.svc + issuer=CN=kong-mesh-selfsigned-ca + notBefore=... + notAfter=... + ``` + {:.no-copy-code} + +1. Confirm cert-manager will renew the certificate automatically: + + ```sh + kubectl get certificate -n kong-mesh-system control-plane-cert + ``` + + The `READY` column should show `True`. + {:.no-copy-code} diff --git a/app/_includes/prereqs/cert-manager.md b/app/_includes/prereqs/cert-manager.md new file mode 100644 index 0000000000..65992d8bec --- /dev/null +++ b/app/_includes/prereqs/cert-manager.md @@ -0,0 +1,12 @@ +Install cert-manager to your cluster. cert-manager issues and rotates certificates automatically. + +```sh +helm repo add jetstack https://charts.jetstack.io +helm repo update +helm upgrade --install \ + cert-manager jetstack/cert-manager \ + --namespace cert-manager \ + --create-namespace \ + --set crds.enabled=true +kubectl wait -n cert-manager --for=condition=ready pod --all --timeout=90s +``` From a6106fa5be2b4663b12dfecd2f6224e87a9203c5 Mon Sep 17 00:00:00 2001 From: Lucie Milan Date: Wed, 17 Jun 2026 11:15:05 +0200 Subject: [PATCH 2/7] Update use-cert-manager-for-control-plane-certificates.md --- .../mesh/use-cert-manager-for-control-plane-certificates.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md b/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md index 1451da7e9e..bbc55ded9a 100644 --- a/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md +++ b/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md @@ -1,6 +1,6 @@ --- title: Use cert-manager for control plane certificates -description: Learn how to use cert-manager to provision and rotate TLS certificates for the Kong Mesh control plane on Kubernetes. +description: Learn how to use cert-manager to provision and rotate TLS certificates for the {{site.mesh_product_name}} control plane on Kubernetes. content_type: how_to permalink: /mesh/use-cert-manager-for-control-plane-certificates/ products: @@ -127,7 +127,7 @@ Wait for the certificate to be issued: kubectl wait -n kong-mesh-system --for=condition=ready certificate/control-plane-cert --timeout=60s ``` -## Install Kong Mesh with the cert-manager certificate +## Install {{site.mesh_product_name}} with the cert-manager certificate Install {{site.mesh_product_name}} and point the control plane TLS configuration at the secret cert-manager created: From 8d14493a4de8862651207767ca47f8920d801caa Mon Sep 17 00:00:00 2001 From: Lucie Milan Date: Wed, 17 Jun 2026 11:51:57 +0200 Subject: [PATCH 3/7] Update use-cert-manager-for-control-plane-certificates.md --- .../use-cert-manager-for-control-plane-certificates.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md b/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md index bbc55ded9a..5cbdb9a46a 100644 --- a/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md +++ b/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md @@ -37,6 +37,14 @@ related_resources: By default, {{site.mesh_product_name}} generates its own self-signed control plane certificates at startup. Using cert-manager lets you manage the full certificate lifecycle — issuance, rotation, and expiry — outside of the control plane itself. This guide walks you through creating the required cert-manager resources and configuring {{site.mesh_product_name}} to use them. +## Create the Kong Mesh namespace + +The cert-manager resources in the following steps are scoped to the `kong-mesh-system` namespace, which {{site.mesh_product_name}} uses at install time. Create it now so the namespace exists before you apply any certificates: + +```sh +kubectl create namespace kong-mesh-system +``` + ## Create a self-signed ClusterIssuer A `ClusterIssuer` is a cluster-scoped resource that cert-manager uses to sign certificates. Create a self-signed one as the root of your certificate chain: @@ -135,7 +143,6 @@ Install {{site.mesh_product_name}} and point the control plane TLS configuration helm repo add kong-mesh https://kong.github.io/kong-mesh-charts helm repo update helm upgrade --install \ - --create-namespace \ --namespace kong-mesh-system \ kong-mesh kong-mesh/kong-mesh \ --set controlPlane.tls.general.secretName=control-plane-cert From 9877e8b63999c1553bcbff2eb646bd56518dfd70 Mon Sep 17 00:00:00 2001 From: Lucie Milan Date: Wed, 17 Jun 2026 11:55:40 +0200 Subject: [PATCH 4/7] fixes --- ...t-manager-for-control-plane-certificates.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md b/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md index 5cbdb9a46a..d95d915e7b 100644 --- a/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md +++ b/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md @@ -164,24 +164,27 @@ Verify that the control plane is running and using the cert-manager-issued certi The `kong-mesh-control-plane` pod should show `Running` in the `STATUS` column. {:.no-copy-code} -1. Inspect the certificate the control plane is serving: +1. Inspect the certificate that cert-manager stored in the secret: ```sh - kubectl exec -n kong-mesh-system deploy/kong-mesh-control-plane -- \ - openssl s_client -connect localhost:5678 -showcerts /dev/null | \ + kubectl get secret -n kong-mesh-system control-plane-cert \ + -o jsonpath='{.data.tls\.crt}' | base64 -d | \ openssl x509 -noout -subject -issuer -dates ``` - The output should show `kong-mesh-selfsigned-ca` as the issuer and an expiry date 90 days from issuance: + The output should show `kong-mesh-selfsigned-ca` as the issuer and an expiry date 90 days from issuance. For example: ```text - subject=CN=kong-mesh-control-plane.kong-mesh-system.svc + subject= issuer=CN=kong-mesh-selfsigned-ca - notBefore=... - notAfter=... + notBefore=Jun 17 09:50:10 2026 GMT + notAfter=Sep 15 09:50:10 2026 GMT ``` {:.no-copy-code} + {:.info} + > The subject is empty because cert-manager sets identity via SANs rather than a common name. + 1. Confirm cert-manager will renew the certificate automatically: ```sh @@ -189,4 +192,3 @@ Verify that the control plane is running and using the cert-manager-issued certi ``` The `READY` column should show `True`. - {:.no-copy-code} From e4fe60919a5a4e9bc8365d1412be90e1e32f0ef1 Mon Sep 17 00:00:00 2001 From: Lucie Milan Date: Wed, 17 Jun 2026 11:59:22 +0200 Subject: [PATCH 5/7] fixes --- .../mesh/use-cert-manager-for-control-plane-certificates.md | 6 +++--- app/_includes/prereqs/cert-manager.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md b/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md index d95d915e7b..8034e52e09 100644 --- a/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md +++ b/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md @@ -35,9 +35,9 @@ related_resources: url: /mesh/deploy-mesh-self-managed/ --- -By default, {{site.mesh_product_name}} generates its own self-signed control plane certificates at startup. Using cert-manager lets you manage the full certificate lifecycle — issuance, rotation, and expiry — outside of the control plane itself. This guide walks you through creating the required cert-manager resources and configuring {{site.mesh_product_name}} to use them. +By default, {{site.mesh_product_name}} generates its own self-signed control plane certificates at startup. Using cert-manager lets you manage the full certificate lifecycle — issuance, rotation, and expiration — outside of the control plane itself. This guide walks you through creating the required cert-manager resources and configuring {{site.mesh_product_name}} to use them. -## Create the Kong Mesh namespace +## Create the {{site.mesh_product_name}} namespace The cert-manager resources in the following steps are scoped to the `kong-mesh-system` namespace, which {{site.mesh_product_name}} uses at install time. Create it now so the namespace exists before you apply any certificates: @@ -172,7 +172,7 @@ Verify that the control plane is running and using the cert-manager-issued certi openssl x509 -noout -subject -issuer -dates ``` - The output should show `kong-mesh-selfsigned-ca` as the issuer and an expiry date 90 days from issuance. For example: + The output should show `kong-mesh-selfsigned-ca` as the issuer and an expiration date 90 days from issuance. For example: ```text subject= diff --git a/app/_includes/prereqs/cert-manager.md b/app/_includes/prereqs/cert-manager.md index 65992d8bec..5c873caa05 100644 --- a/app/_includes/prereqs/cert-manager.md +++ b/app/_includes/prereqs/cert-manager.md @@ -1,4 +1,4 @@ -Install cert-manager to your cluster. cert-manager issues and rotates certificates automatically. +Install cert-manager in your cluster. cert-manager issues and rotates certificates automatically. ```sh helm repo add jetstack https://charts.jetstack.io From 6075e9cf0b93dd2b399ea2af2e46a6fca8151f17 Mon Sep 17 00:00:00 2001 From: Lucie Milan Date: Wed, 17 Jun 2026 12:01:37 +0200 Subject: [PATCH 6/7] add links --- app/_how-tos/mesh/deploy-mesh-self-managed.md | 2 ++ .../mesh/use-cert-manager-for-control-plane-certificates.md | 2 ++ app/_indices/mesh.yaml | 1 + app/mesh/cert-manager.md | 2 ++ 4 files changed, 7 insertions(+) diff --git a/app/_how-tos/mesh/deploy-mesh-self-managed.md b/app/_how-tos/mesh/deploy-mesh-self-managed.md index e0e2fb4f00..b0c0cd4c31 100644 --- a/app/_how-tos/mesh/deploy-mesh-self-managed.md +++ b/app/_how-tos/mesh/deploy-mesh-self-managed.md @@ -8,6 +8,8 @@ bread-crumbs: related_resources: - text: "{{site.mesh_product_name}}" url: /mesh/overview/ + - text: Use cert-manager for control plane certificates + url: /mesh/use-cert-manager-for-control-plane-certificates/ products: - mesh diff --git a/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md b/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md index 8034e52e09..4c24361d09 100644 --- a/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md +++ b/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md @@ -33,6 +33,8 @@ related_resources: url: /mesh/deploy-mesh-on-kubernetes/ - text: Deploy Mesh (self-managed) url: /mesh/deploy-mesh-self-managed/ + - text: Kubernetes cert-manager CA policy (data plane certificates) + url: /mesh/cert-manager/ --- By default, {{site.mesh_product_name}} generates its own self-signed control plane certificates at startup. Using cert-manager lets you manage the full certificate lifecycle — issuance, rotation, and expiration — outside of the control plane itself. This guide walks you through creating the required cert-manager resources and configuring {{site.mesh_product_name}} to use them. diff --git a/app/_indices/mesh.yaml b/app/_indices/mesh.yaml index 59e4e221ae..193be9c945 100644 --- a/app/_indices/mesh.yaml +++ b/app/_indices/mesh.yaml @@ -114,6 +114,7 @@ sections: - path: /mesh/signed-images/ - path: /mesh/issue-identity-with-meshidentity/ - path: /mesh/issue-identity-with-meshidentity-spire/ + - path: /mesh/use-cert-manager-for-control-plane-certificates/ - title: Observability items: diff --git a/app/mesh/cert-manager.md b/app/mesh/cert-manager.md index 1d603c0fc6..48fa7b90d0 100644 --- a/app/mesh/cert-manager.md +++ b/app/mesh/cert-manager.md @@ -31,6 +31,8 @@ related_resources: url: /mesh/ca-rotation/ - text: "{{site.mesh_product_name}} enterprise features" url: /mesh/enterprise/ + - text: Use cert-manager for control plane certificates + url: /mesh/use-cert-manager-for-control-plane-certificates/ --- You can use Kubernetes cert-manager as an mTLS backend for issuing Data Plane certificates in {{site.mesh_product_name}}. From 16a5efda9afe864d9c312572b6fb8221a34c27da Mon Sep 17 00:00:00 2001 From: Lucie Milan Date: Wed, 17 Jun 2026 12:54:44 +0200 Subject: [PATCH 7/7] copy edits --- ...-manager-for-control-plane-certificates.md | 73 ++++++++++--------- app/_includes/prereqs/cert-manager.md | 2 +- 2 files changed, 38 insertions(+), 37 deletions(-) diff --git a/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md b/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md index 4c24361d09..b0d88dfdf4 100644 --- a/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md +++ b/app/_how-tos/mesh/use-cert-manager-for-control-plane-certificates.md @@ -37,11 +37,11 @@ related_resources: url: /mesh/cert-manager/ --- -By default, {{site.mesh_product_name}} generates its own self-signed control plane certificates at startup. Using cert-manager lets you manage the full certificate lifecycle — issuance, rotation, and expiration — outside of the control plane itself. This guide walks you through creating the required cert-manager resources and configuring {{site.mesh_product_name}} to use them. +By default, {{site.mesh_product_name}} generates its own self-signed control plane certificates at startup. Using cert-manager lets you manage the full certificate lifecycle, issuance, rotation, and expiration, outside of the control plane itself. This guide walks you through creating the required cert-manager resources and configuring {{site.mesh_product_name}} to use them. ## Create the {{site.mesh_product_name}} namespace -The cert-manager resources in the following steps are scoped to the `kong-mesh-system` namespace, which {{site.mesh_product_name}} uses at install time. Create it now so the namespace exists before you apply any certificates: +The cert-manager resources in the following steps are scoped to the `kong-mesh-system` namespace, which {{site.mesh_product_name}} uses at install time: ```sh kubectl create namespace kong-mesh-system @@ -102,40 +102,40 @@ spec: ## Create the control plane certificate -Create a `Certificate` resource that cert-manager uses to issue and renew the control plane TLS certificate. The `dnsNames` must include all the DNS names that data planes use to reach the control plane: - -```sh -echo "apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: control-plane-cert - namespace: kong-mesh-system -spec: - secretName: control-plane-cert - duration: 2160h # 90d - renewBefore: 360h # 15d - isCA: false - privateKey: - algorithm: RSA - encoding: PKCS1 - size: 2048 - usages: - - server auth - dnsNames: - - kong-mesh-control-plane.kong-mesh-system.svc - - kong-mesh-control-plane - - kong-mesh-control-plane.kong-mesh-system - - kong-mesh-control-plane.kong-mesh-system.svc.local - issuerRef: - name: kong-mesh-issuer - kind: Issuer" | kubectl apply -f - -``` +1. Create a `Certificate` resource that cert-manager uses to issue and renew the control plane TLS certificate. The `dnsNames` must include all the DNS names that data planes use to reach the control plane: + + ```sh + echo "apiVersion: cert-manager.io/v1 + kind: Certificate + metadata: + name: control-plane-cert + namespace: kong-mesh-system + spec: + secretName: control-plane-cert + duration: 2160h + renewBefore: 360h + isCA: false + privateKey: + algorithm: RSA + encoding: PKCS1 + size: 2048 + usages: + - server auth + dnsNames: + - kong-mesh-control-plane.kong-mesh-system.svc + - kong-mesh-control-plane + - kong-mesh-control-plane.kong-mesh-system + - kong-mesh-control-plane.kong-mesh-system.svc.local + issuerRef: + name: kong-mesh-issuer + kind: Issuer" | kubectl apply -f - + ``` -Wait for the certificate to be issued: +1. Wait for the certificate to be issued: -```sh -kubectl wait -n kong-mesh-system --for=condition=ready certificate/control-plane-cert --timeout=60s -``` + ```sh + kubectl wait -n kong-mesh-system --for=condition=ready certificate/control-plane-cert --timeout=60s + ``` ## Install {{site.mesh_product_name}} with the cert-manager certificate @@ -151,11 +151,12 @@ helm upgrade --install \ kubectl wait -n kong-mesh-system --for=condition=ready pod --selector=app=kong-mesh-control-plane --timeout=90s ``` -If {{site.mesh_product_name}} is already installed, run `helm upgrade` instead of `helm install` with the same `--set` flag. +{:.info} +> If {{site.mesh_product_name}} is already installed, run `helm upgrade` instead of `helm install` with the same `--set` flag. ## Validate -Verify that the control plane is running and using the cert-manager-issued certificate: +Verify that the control plane is running and using the cert-manager-issued certificate. 1. Confirm the control plane pod is healthy: diff --git a/app/_includes/prereqs/cert-manager.md b/app/_includes/prereqs/cert-manager.md index 5c873caa05..e57bf9729f 100644 --- a/app/_includes/prereqs/cert-manager.md +++ b/app/_includes/prereqs/cert-manager.md @@ -1,4 +1,4 @@ -Install cert-manager in your cluster. cert-manager issues and rotates certificates automatically. +Install cert-manager in your cluster to issue and rotate certificates automatically: ```sh helm repo add jetstack https://charts.jetstack.io