From 3e9b438e7c3a756dd4c6160a7c793d97ab92053f Mon Sep 17 00:00:00 2001 From: Antoine C Date: Wed, 15 May 2024 12:24:44 +0100 Subject: [PATCH] helm: add least privileges logic for secrets on ceph-csi-cephfs chart this allows the encryption KMS config to be granted secret access with a least privilges policy. Signed-off-by: Antoine C --- charts/ceph-csi-cephfs/README.md | 11 +++++++++++ .../templates/nodeplugin-clusterrole.yaml | 3 +-- charts/ceph-csi-cephfs/templates/nodeplugin-role.yaml | 5 +++-- .../templates/nodeplugin-rolebinding.yaml | 6 +++--- charts/ceph-csi-cephfs/values.yaml | 3 +++ 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/charts/ceph-csi-cephfs/README.md b/charts/ceph-csi-cephfs/README.md index aeafa0a77..6c010db21 100644 --- a/charts/ceph-csi-cephfs/README.md +++ b/charts/ceph-csi-cephfs/README.md @@ -83,6 +83,16 @@ storageClass: encryptionKMSID: kubernetes ``` +#### Least privilege secret access + +If you use the `metadata` and let RBAC created by the chart, permissions +will be given to access **only** the secret referenced in the +`encryptionKMSConfig`. This is something important to keep in mind, as a +manual change to the config to point to another secret or add further KMS +config will not be authorized. If you wish to give CephCSI a global secret +access to the cluster, you may set `rbac.leastPrivileges` to `false`, and +permissions will be granted globally via a *ClusterRole*. + #### Known Issues Upgrading - When upgrading to version >=3.7.0, you might encounter an error that the @@ -127,6 +137,7 @@ charts and their default values. | Parameter | Description | Default | | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | | `rbac.create` | Specifies whether RBAC resources should be created | `true` | +| `rbac.leastPrivileges` | Specifies whether RBAC resources should be created with a restricted scope when supported (only secrets supported currently) | `true` | | `serviceAccounts.nodeplugin.create` | Specifies whether a nodeplugin ServiceAccount should be created | `true` | | `serviceAccounts.nodeplugin.name` | The name of the nodeplugin ServiceAccount to use. If not set and create is true, a name is generated using the fullname | "" | | `serviceAccounts.provisioner.create` | Specifies whether a provisioner ServiceAccount should be created | `true` | diff --git a/charts/ceph-csi-cephfs/templates/nodeplugin-clusterrole.yaml b/charts/ceph-csi-cephfs/templates/nodeplugin-clusterrole.yaml index d11e3eef0..dfd2ea9f8 100644 --- a/charts/ceph-csi-cephfs/templates/nodeplugin-clusterrole.yaml +++ b/charts/ceph-csi-cephfs/templates/nodeplugin-clusterrole.yaml @@ -3,7 +3,6 @@ kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: {{ include "ceph-csi-cephfs.nodeplugin.fullname" . }} - namespace: {{ .Release.Namespace }} labels: app: {{ include "ceph-csi-cephfs.name" . }} chart: {{ include "ceph-csi-cephfs.chart" . }} @@ -19,7 +18,7 @@ rules: - apiGroups: [""] resources: ["configmaps"] verbs: ["get"] -{{- if and .Values.encryptionKMSConfig .Values.encryptionKMSConfig.secretNamespace (not (eq .Values.encryptionKMSConfig.secretNamespace .Release.Namespace)) }} +{{- if and .Values.encryptionKMSConfig .Values.encryptionKMSConfig.secretNamespace (not .Values.rbac.leastPrivileges) }} # allow to read the encryption key used with the metadata KMS - apiGroups: [""] resources: ["secrets"] diff --git a/charts/ceph-csi-cephfs/templates/nodeplugin-role.yaml b/charts/ceph-csi-cephfs/templates/nodeplugin-role.yaml index d498284aa..a9a243c7d 100644 --- a/charts/ceph-csi-cephfs/templates/nodeplugin-role.yaml +++ b/charts/ceph-csi-cephfs/templates/nodeplugin-role.yaml @@ -1,9 +1,10 @@ -{{- if .Values.rbac.create -}} -{{- if and .Values.encryptionKMSConfig .Values.encryptionKMSConfig.secretNamespace .Values.encryptionKMSConfig.secretName (eq .Values.encryptionKMSConfig.secretNamespace .Release.Namespace) -}} +{{- if and .Values.rbac.create .Values.rbac.leastPrivileges -}} +{{- if and .Values.encryptionKMSConfig (eq .Values.encryptionKMSConfig.encryptionKMSType "metadata") .Values.encryptionKMSConfig.secretNamespace .Values.encryptionKMSConfig.secretName -}} kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: {{ include "ceph-csi-cephfs.nodeplugin.fullname" . }} + namespace: {{ .Values.encryptionKMSConfig.secretNamespace }} labels: app: {{ include "ceph-csi-cephfs.name" . }} chart: {{ include "ceph-csi-cephfs.chart" . }} diff --git a/charts/ceph-csi-cephfs/templates/nodeplugin-rolebinding.yaml b/charts/ceph-csi-cephfs/templates/nodeplugin-rolebinding.yaml index c76e96f2f..0be11b542 100644 --- a/charts/ceph-csi-cephfs/templates/nodeplugin-rolebinding.yaml +++ b/charts/ceph-csi-cephfs/templates/nodeplugin-rolebinding.yaml @@ -1,10 +1,10 @@ -{{- if .Values.rbac.create -}} -{{- if and (eq .Values.encryptionKMSConfig.encryptionKMSType "metadata") (eq .Values.encryptionKMSConfig.secretNamespace .Release.Namespace) -}} +{{- if and .Values.rbac.create .Values.rbac.leastPrivileges -}} +{{- if and .Values.encryptionKMSConfig (eq .Values.encryptionKMSConfig.encryptionKMSType "metadata") .Values.encryptionKMSConfig.secretNamespace -}} kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: {{ include "ceph-csi-cephfs.nodeplugin.fullname" . }} - namespace: {{ .Release.Namespace }} + namespace: {{ .Values.encryptionKMSConfig.secretNamespace }} labels: app: {{ include "ceph-csi-cephfs.name" . }} chart: {{ include "ceph-csi-cephfs.chart" . }} diff --git a/charts/ceph-csi-cephfs/values.yaml b/charts/ceph-csi-cephfs/values.yaml index f05b605b6..fa611cae3 100644 --- a/charts/ceph-csi-cephfs/values.yaml +++ b/charts/ceph-csi-cephfs/values.yaml @@ -2,6 +2,9 @@ rbac: # Specifies whether RBAC resources should be created create: true + # When possible try and reduce the scope of permission to only give + # access to resources defined in the config. See the README for more info + leastPrivileges: true serviceAccounts: nodeplugin: