Skip to content

Certificate Management

Nantian Gateway’s gRPC control plane can use TLS or mutual TLS to secure the xDS stream between control plane and data plane. The Helm chart provides two certificate generation strategies: self-signed certificates for development and testing, or cert-manager integration for production.

For the TLS and mTLS settings that consume these certificates, see TLS / mTLS.

The chart can generate the three certificates needed for gRPC mTLS: a CA certificate, a server certificate for the control plane, and a client certificate for each data plane. Generation happens once at install time and the results are stored in Kubernetes Secrets. On upgrades, the chart reuses the existing Secrets.

Certificate management is configured under the certs key:

certs:
generate: true
domain: ""
selfSigned:
caDurationDays: 365
serverDurationDays: 90
clientDurationDays: 90
certManager:
enabled: false
issuerRef:
name: ""
kind: ClusterIssuer
group: cert-manager.io
duration: 2160h
renewBefore: 360h
ParameterTypeDefaultDescription
certs.generatebooltrueGenerate self-signed certificates at install time
certs.domainstring""Namespace-scoped domain for the gRPC server certificate SAN. Auto-computed from release name and namespace when left empty
certs.selfSigned.caDurationDaysint365Validity period in days for the self-signed CA certificate
certs.selfSigned.serverDurationDaysint90Validity period in days for the self-signed server certificate
certs.selfSigned.clientDurationDaysint90Validity period in days for the self-signed client certificate
certs.certManager.enabledboolfalseUse cert-manager to issue certificates instead of self-signed generation
certs.certManager.issuerRef.namestring""Name of the cert-manager Issuer or ClusterIssuer
certs.certManager.issuerRef.kindstring"ClusterIssuer"Kind of the cert-manager issuer (Issuer or ClusterIssuer)
certs.certManager.issuerRef.groupstring"cert-manager.io"API group of the cert-manager issuer
certs.certManager.durationstring"2160h"Requested certificate duration (90 days)
certs.certManager.renewBeforestring"360h"Renew certificate this far before expiry (15 days)

Set certs.generate: true to create self-signed certificates. This mode is suitable for development, testing, and non-production environments where you don’t have cert-manager running.

certs:
generate: true
selfSigned:
caDurationDays: 365
serverDurationDays: 90
clientDurationDays: 90

The chart creates three Secrets in the release namespace:

  • nantian-gw-grpc-ca: CA certificate and key
  • nantian-gw-grpc-server-tls: gRPC server certificate and key
  • nantian-gw-grpc-client-tls: gRPC client certificate and key

The domain for the server certificate’s SAN field is auto-computed as <release-name>.<namespace>.svc unless you set certs.domain explicitly. This ensures the data plane can verify the server’s identity when connecting to the cluster-internal gRPC service.

After enabling certificate generation, enable gRPC TLS in the control plane configuration so the certificates are actually used. The TLS / mTLS page covers those settings.

For production environments with cert-manager installed, use certs.certManager.enabled: true. This delegates certificate lifecycle management to cert-manager, which handles issuance, rotation, and renewal automatically.

certs:
certManager:
enabled: true
issuerRef:
name: nantian-gw-ca-issuer
kind: ClusterIssuer
group: cert-manager.io
duration: 2160h
renewBefore: 360h

You must create the issuer before installing or upgrading the chart. A ClusterIssuer works across all namespaces, while an Issuer is scoped to a single namespace:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: nantian-gw-ca-issuer
spec:
ca:
secretName: nantian-gw-root-ca

The chart creates three Certificate resources (CA, server, client) referencing your issuer. cert-manager handles the rest: it generates keys, requests certificates from the issuer, stores them in Secrets, and rotates them before they expire.

ModeUse caseRotation
certs.generate: falseYou provide your own Secrets or don’t use gRPC TLSManual
certs.generate: true (default, self-signed)Development, testing, ephemeral clustersManual (reinstall or rotate by hand)
certs.certManager.enabled: trueProduction clusters with cert-managerAutomatic via cert-manager

When neither self-signed generation nor cert-manager is enabled, the chart expects you to have created the three TLS Secrets (nantian-gw-grpc-ca, nantian-gw-grpc-server-tls, nantian-gw-grpc-client-tls) yourself. This gives you full control over the certificate lifecycle using your own PKI or tooling.

For public-facing gateway listeners, combine cert-manager with Let’s Encrypt for automated TLS certificate provisioning:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod-key
solvers:
- http01:
ingress:
class: nginx

Then reference this issuer in your Gateway listener’s TLS configuration. cert-manager automatically requests, renews, and replaces certificates before expiry.

Terminal window
kubectl describe certificaterequest -n nantian-gw
kubectl describe order -n nantian-gw # For ACME issuers

Common failure reasons:

  • Issuer not found: Verify certs.certManager.issuerRef.name matches an existing Issuer or ClusterIssuer
  • DNS validation failed: For ACME, check that the domain’s DNS records are resolvable and the solver configuration is correct
  • Rate limiting: Let’s Encrypt enforces rate limits (50 certificates per domain per week). Use the staging environment (https://acme-staging-v02.api.letsencrypt.org/directory) for testing
Terminal window
kubectl get certificate -n nantian-gw -o wide

The Ready and Renewal Time columns show certificate status. cert-manager renews certificates at renewBefore (default 15 days before expiry). Force manual renewal:

Terminal window
kubectl annotate certificate nantian-gw-grpc-server-tls -n nantian-gw \
cert-manager.io/issuer-kind=ClusterIssuer \
cert-manager.io/issuer-name=nantian-gw-ca-issuer

gRPC connection refused after certificate rotation

Section titled “gRPC connection refused after certificate rotation”

If data planes lose connection after certificate rotation, they may be using a cached, expired certificate. Restart data plane pods to force a fresh connection:

Terminal window
kubectl rollout restart deployment/nantian-gw-dataplane -n nantian-gw