Best Practice
Learn how to deploy cert-manager to comply with popular security standards such as the CIS Kubernetes Benchmark, the NSA Kubernetes Hardening Guide, or the BSI Kubernetes Security Recommendations.
Overview
The default cert-manager resources in the Helm chart or YAML manifests (Deployment, Pod, ServiceAccount etc) are designed for backwards compatibility rather than for best practice or maximum security. You may find that the default resources do not comply with the security policy on your Kubernetes cluster and in that case you can modify the installation configuration using Helm chart values to override the defaults.
Restrict Auto-Mount of Service Account Tokens
This recommendation is described in the Kyverno Policy Catalogue as follows:
Kubernetes automatically mounts ServiceAccount credentials in each Pod. The ServiceAccount may be assigned roles allowing Pods to access API resources. Blocking this ability is an extension of the least privilege best practice and should be followed if Pods do not need to speak to the API server to function. This policy ensures that mounting of these ServiceAccount tokens is blocked
The cert-manager components do need to speak to the API server but we still recommend setting automountServiceAccountToken: false
for the following reasons:
- Setting
automountServiceAccountToken: false
will allow cert-manager to be installed on clusters where Kyverno (or some other policy system) is configured to deny Pods that have this field set totrue
. The Kubernetes default value istrue
. - With
automountServiceAccountToken: true
, all the containers in the Pod will mount the ServiceAccount token, including side-car and init containers that might have been injected into the cert-manager Pod resources by Kubernetes admission controllers. The principle of least privilege suggests that it is better to explicitly mount the ServiceAccount token into the cert-manager containers.
So it is recommended to set automountServiceAccountToken: false
and manually add a projected Volume
to each of the cert-manager Deployment resources, containing the ServiceAccount token, CA certificate and namespace files that would normally be added automatically by the Kubernetes ServiceAccount controller,
and to explicitly add a read-only VolumeMount
to each of the cert-manager containers.
An example of this configuration is included in the Helm Chart Values file below.
Best Practice Helm Chart Values
Download the following Helm chart values file and supply it to helm install
, helm upgrade
, or helm template
using the --values
flag:
# Helm chart values which make cert-manager comply with CIS, BSI and NSA# security benchmarks and other best practices for deploying cert-manager in# production.## Read the rationale for these values in:# * https://cert-manager.io/docs/installation/best-practice/global:priorityClassName: system-cluster-criticalreplicaCount: 2podDisruptionBudget:enabled: trueminAvailable: 1automountServiceAccountToken: falseserviceAccount:automountServiceAccountToken: falsevolumes:- name: serviceaccount-tokenprojected:defaultMode: 0444sources:- serviceAccountToken:expirationSeconds: 3607path: token- configMap:name: kube-root-ca.crtitems:- key: ca.crtpath: ca.crt- downwardAPI:items:- path: namespacefieldRef:apiVersion: v1fieldPath: metadata.namespacevolumeMounts:- mountPath: /var/run/secrets/kubernetes.io/serviceaccountname: serviceaccount-tokenreadOnly: truewebhook:replicaCount: 3podDisruptionBudget:enabled: trueminAvailable: 1automountServiceAccountToken: falseserviceAccount:automountServiceAccountToken: falsevolumes:- name: serviceaccount-tokenprojected:defaultMode: 0444sources:- serviceAccountToken:expirationSeconds: 3607path: token- configMap:name: kube-root-ca.crtitems:- key: ca.crtpath: ca.crt- downwardAPI:items:- path: namespacefieldRef:apiVersion: v1fieldPath: metadata.namespacevolumeMounts:- mountPath: /var/run/secrets/kubernetes.io/serviceaccountname: serviceaccount-tokenreadOnly: truecainjector:extraArgs:- --namespace=cert-manager- --enable-certificates-data-source=falsereplicaCount: 2podDisruptionBudget:enabled: trueminAvailable: 1automountServiceAccountToken: falseserviceAccount:automountServiceAccountToken: falsevolumes:- name: serviceaccount-tokenprojected:defaultMode: 0444sources:- serviceAccountToken:expirationSeconds: 3607path: token- configMap:name: kube-root-ca.crtitems:- key: ca.crtpath: ca.crt- downwardAPI:items:- path: namespacefieldRef:apiVersion: v1fieldPath: metadata.namespacevolumeMounts:- mountPath: /var/run/secrets/kubernetes.io/serviceaccountname: serviceaccount-tokenreadOnly: truestartupapicheck:automountServiceAccountToken: falseserviceAccount:automountServiceAccountToken: falsevolumes:- name: serviceaccount-tokenprojected:defaultMode: 0444sources:- serviceAccountToken:expirationSeconds: 3607path: token- configMap:name: kube-root-ca.crtitems:- key: ca.crtpath: ca.crt- downwardAPI:items:- path: namespacefieldRef:apiVersion: v1fieldPath: metadata.namespacevolumeMounts:- mountPath: /var/run/secrets/kubernetes.io/serviceaccountname: serviceaccount-tokenreadOnly: true
Other
This list of recommendations is a work-in-progress. If you have other best practice recommendations please contribute to this page.