NEW: Get project updates onTwitterandMastodon

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:

  1. 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 to true. The Kubernetes default value is true.
  2. 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:

🔗 values.best-practice.yaml

# Helm chart values which make cert-manager comply with CIS, BSI and NSA
# security benchmarks.
automountServiceAccountToken: false
serviceAccount:
automountServiceAccountToken: false
volumes:
- name: serviceaccount-token
projected:
defaultMode: 0444
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
name: kube-root-ca.crt
items:
- key: ca.crt
path: ca.crt
- downwardAPI:
items:
- path: namespace
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: serviceaccount-token
readOnly: true
webhook:
automountServiceAccountToken: false
serviceAccount:
automountServiceAccountToken: false
volumes:
- name: serviceaccount-token
projected:
defaultMode: 0444
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
name: kube-root-ca.crt
items:
- key: ca.crt
path: ca.crt
- downwardAPI:
items:
- path: namespace
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: serviceaccount-token
readOnly: true
cainjector:
automountServiceAccountToken: false
serviceAccount:
automountServiceAccountToken: false
volumes:
- name: serviceaccount-token
projected:
defaultMode: 0444
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
name: kube-root-ca.crt
items:
- key: ca.crt
path: ca.crt
- downwardAPI:
items:
- path: namespace
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: serviceaccount-token
readOnly: true
startupapicheck:
automountServiceAccountToken: false
serviceAccount:
automountServiceAccountToken: false
volumes:
- name: serviceaccount-token
projected:
defaultMode: 0444
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
name: kube-root-ca.crt
items:
- key: ca.crt
path: ca.crt
- downwardAPI:
items:
- path: namespace
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: serviceaccount-token
readOnly: true

Other

This list of recommendations is a work-in-progress. If you have other best practice recommendations please contribute to this page.