Skip to content

Commit

Permalink
More secure rbac (kedacore#625)
Browse files Browse the repository at this point in the history
Signed-off-by: Jirka Kremser <jiri.kremser@gmail.com>
Signed-off-by: Jirka Kremser <535866+jkremser@users.noreply.github.com>
Co-authored-by: Jan Wozniak <wozniak.jan@gmail.com>
  • Loading branch information
2 people authored and QuentinBisson committed Jul 1, 2024
1 parent 3ec46c7 commit 42ce6e9
Show file tree
Hide file tree
Showing 20 changed files with 381 additions and 143 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# IDE specific files
.vscode
.idea
*.swp
*.swo

# Mac
.DS_Store
29 changes: 21 additions & 8 deletions keda/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ helm repo add kedacore https://kedacore.github.io/charts
helm repo update

kubectl create namespace keda
helm install keda kedacore/keda --namespace keda --version 2.13.0
helm install keda kedacore/keda --namespace keda --version 2.13.1
```

## Introduction
Expand All @@ -36,7 +36,7 @@ To install the chart with the release name `keda`:

```console
$ kubectl create namespace keda
$ helm install keda kedacore/keda --namespace keda --version 2.13.0
$ helm install keda kedacore/keda --namespace keda --version 2.13.1
```

## Uninstalling the Chart
Expand Down Expand Up @@ -111,11 +111,10 @@ their default values.
| `priorityClassName` | string | `""` | priorityClassName for all KEDA components |
| `rbac.aggregateToDefaultRoles` | bool | `false` | Specifies whether RBAC for CRDs should be [aggregated](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#aggregated-clusterroles) to default roles (view, edit, admin) |
| `rbac.create` | bool | `true` | Specifies whether RBAC should be used |
| `rbac.enabledCustomScaledRefKinds` | bool | `true` | Whether RBAC for configured CRDs that can have a `scale` subresource should be created |
| `rbac.scaledRefKinds` | string | `nil` | List of custom resources that support the `scale` subresource and can be referenced by `scaledobject.spec.scaleTargetRef`. The feature needs to be also enabled by `enabledCustomScaledRefKinds`. If left empty, RBAC for `apiGroups: *` and `resources: */scale` will be created.
note: `Deployments` and `StatefulSets` are always enabled |
| `securityContext` | object | [See below](#KEDA-is-secure-by-default) | [Security context] for all containers |
| `serviceAccount.annotations` | object | `{}` | Annotations to add to the service account |
| `serviceAccount.automountServiceAccountToken` | bool | `true` | Specifies whether a service account should automount API-Credentials |
| `serviceAccount.create` | bool | `true` | Specifies whether a service account should be created |
| `serviceAccount.name` | string | `"keda-operator"` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template |
| `tolerations` | list | `[]` | Tolerations for pod scheduling ([docs](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/)) |
| `watchNamespace` | string | `""` | Defines Kubernetes namespaces to watch to scale their workloads. Default watches all namespaces |

Expand All @@ -129,6 +128,7 @@ their default values.
| `image.keda.tag` | string | `""` | Image tag of KEDA operator. Optional, given app version of Helm chart is used by default |
| `logging.operator.format` | string | `"console"` | Logging format for KEDA Operator. allowed values: `json` or `console` |
| `logging.operator.level` | string | `"info"` | Logging level for KEDA Operator. allowed values: `debug`, `info`, `error`, or an integer value greater than 0, specified as string |
| `logging.operator.stackTracesEnabled` | bool | `false` | If enabled, the stack traces will be also printed |
| `logging.operator.timeEncoding` | string | `"rfc3339"` | Logging time encoding for KEDA Operator. allowed values are `epoch`, `millis`, `nano`, `iso8601`, `rfc3339` or `rfc3339nano` |
| `operator.affinity` | object | `{"podAntiAffinity":{"requiredDuringSchedulingIgnoredDuringExecution":[{"labelSelector":{"matchExpressions":[{"key":"app","operator":"In","values":["keda-operator"]}]},"topologyKey":"kubernetes.io/hostname"}]}}` | [Affinity] for pod scheduling for KEDA operator. Takes precedence over the `affinity` field |
| `operator.disableCompression` | bool | `true` | Disable response compression for k8s restAPI in client-go. Disabling compression simply means that turns off the process of making data smaller for K8s restAPI in client-go for faster transmission. |
Expand All @@ -139,13 +139,18 @@ their default values.
| `operator.readinessProbe` | object | `{"failureThreshold":3,"initialDelaySeconds":20,"periodSeconds":3,"successThreshold":1,"timeoutSeconds":1}` | Readiness probes for operator ([docs](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-readiness-probes)) |
| `operator.replicaCount` | int | `1` | Capability to configure the number of replicas for KEDA operator. While you can run more replicas of our operator, only one operator instance will be the leader and serving traffic. You can run multiple replicas, but they will not improve the performance of KEDA, it could only reduce downtime during a failover. Learn more in [our documentation](https://keda.sh/docs/latest/operate/cluster/#high-availability). |
| `operator.revisionHistoryLimit` | int | `10` | ReplicaSets for this Deployment you want to retain (Default: 10) |
| `permissions.operator.restrict.secret` | bool | `false` | Restrict Secret Access for KEDA operator |
| `permissions.operator.restrict.namesAllowList` | list | `[]` | Array of strings denoting what secrets the KEDA operator will be able to read, this takes into account also the configured `watchNamespace`. the default is an empty array -> no restriction on the secret name |
| `permissions.operator.restrict.secret` | bool | `false` | Restrict Secret Access for KEDA operator if true, KEDA operator will be able to read only secrets in {{ .Release.Namespace }} namespace |
| `podAnnotations.keda` | object | `{}` | Pod annotations for KEDA operator |
| `podDisruptionBudget.operator` | object | `{}` | Capability to configure [Pod Disruption Budget] |
| `podLabels.keda` | object | `{}` | Pod labels for KEDA operator |
| `podSecurityContext.operator` | object | [See below](#KEDA-is-secure-by-default) | [Pod security context] of the KEDA operator pod |
| `resources.operator` | object | `{"limits":{"cpu":1,"memory":"1000Mi"},"requests":{"cpu":"100m","memory":"100Mi"}}` | Manage [resource request & limits] of KEDA operator pod |
| `securityContext.operator` | object | [See below](#KEDA-is-secure-by-default) | [Security context] of the operator container |
| `serviceAccount.operator.annotations` | object | `{}` | Annotations to add to the service account |
| `serviceAccount.operator.automountServiceAccountToken` | bool | `true` | Specifies whether a service account should automount API-Credentials |
| `serviceAccount.operator.create` | bool | `true` | Specifies whether a service account should be created |
| `serviceAccount.operator.name` | string | `"keda-operator"` | The name of the service account to use. |
| `topologySpreadConstraints.operator` | list | `[]` | [Pod Topology Constraints] of KEDA operator pod |
| `upgradeStrategy.operator` | object | `{"rollingUpdate":{"maxSurge":1,"maxUnavailable":1},"type":"RollingUpdate"}` | Capability to configure [Deployment upgrade strategy] for operator |
| `verticalPodAutoscaler.keda.cpu.maxAllowed` | int | `2` | |
Expand Down Expand Up @@ -185,6 +190,10 @@ their default values.
| `service.portHttps` | int | `443` | HTTPS port for KEDA Metric Server service |
| `service.portHttpsTarget` | int | `6443` | HTTPS port for KEDA Metric Server container |
| `service.type` | string | `"ClusterIP"` | KEDA Metric Server service type |
| `serviceAccount.metricServer.annotations` | object | `{}` | Annotations to add to the service account |
| `serviceAccount.metricServer.automountServiceAccountToken` | bool | `true` | Specifies whether a service account should automount API-Credentials |
| `serviceAccount.metricServer.create` | bool | `true` | Specifies whether a service account should be created |
| `serviceAccount.metricServer.name` | string | `"keda-metrics-server"` | The name of the service account to use. |
| `topologySpreadConstraints.metricsServer` | list | `[]` | [Pod Topology Constraints] of KEDA metrics apiserver pod |
| `upgradeStrategy.metricsApiServer` | object | `{"rollingUpdate":{"maxSurge":1,"maxUnavailable":1},"type":"RollingUpdate"}` | Capability to configure [Deployment upgrade strategy] for Metrics Api Server |
| `verticalPodAutoscaler.metricsApiServer.cpu.maxAllowed` | int | `2` | |
Expand Down Expand Up @@ -298,8 +307,12 @@ their default values.
| `podDisruptionBudget.webhooks` | object | `{}` | Capability to configure [Pod Disruption Budget] |
| `podLabels.webhooks` | object | `{}` | Pod labels for KEDA Admission webhooks |
| `podSecurityContext.webhooks` | object | [See below](#KEDA-is-secure-by-default) | [Pod security context] of the KEDA admission webhooks |
| `resources.webhooks` | object | `{"limits":{"cpu":"50m","memory":"100Mi"},"requests":{"cpu":"10m","memory":"10Mi"}}` | Manage [resource request & limits] of KEDA admission webhooks pod |
| `resources.webhooks` | object | `{"limits":{"cpu":1,"memory":"1000Mi"},"requests":{"cpu":"100m","memory":"100Mi"}}` | Manage [resource request & limits] of KEDA admission webhooks pod |
| `securityContext.webhooks` | object | [See below](#KEDA-is-secure-by-default) | [Security context] of the admission webhooks container |
| `serviceAccount.webhooks.annotations` | object | `{}` | Annotations to add to the service account |
| `serviceAccount.webhooks.automountServiceAccountToken` | bool | `true` | Specifies whether a service account should automount API-Credentials |
| `serviceAccount.webhooks.create` | bool | `true` | Specifies whether a service account should be created |
| `serviceAccount.webhooks.name` | string | `"keda-webhook"` | The name of the service account to use. |
| `topologySpreadConstraints.webhooks` | list | `[]` | [Pod Topology Constraints] of KEDA admission webhooks pod |
| `upgradeStrategy.webhooks` | object | `{"rollingUpdate":{"maxSurge":1,"maxUnavailable":1},"type":"RollingUpdate"}` | Capability to configure [Deployment upgrade strategy] for Admission webhooks |
| `volumes.webhooks.extraVolumeMounts` | list | `[]` | Extra volume mounts for admission webhooks deployment |
Expand Down
7 changes: 7 additions & 0 deletions keda/templates/NOTES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ WARNING - Running on unsupported Kubernetes version "1.{{.Capabilities.KubeVersi
-------------------------------------------------------------------------------------
{{- end }}

{{- if .Values.serviceAccount.name }}
-------------------------------------------------------------------------------------
WARNING - .serviceAccount.name has been deprecated, please migrate to newest version of the Helm Chart values that allows overriding the service account name for each KEDA component.
New version: serviceAccount.{operator,metricServer,webhooks}.{create,name,automountServiceAccountToken,annotations}
-------------------------------------------------------------------------------------
{{- end }}

Learn more about KEDA:
- Documentation: https://keda.sh/
- Support: https://keda.sh/support/
Expand Down
71 changes: 26 additions & 45 deletions keda/templates/manager/clusterrole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ rules:
resources:
- configmaps
- configmaps/status
- limitranges
- pods
- services
- serviceaccounts
verbs:
- get
- list
Expand All @@ -26,39 +30,27 @@ rules:
- events
verbs:
- '*'
{{- if not .Values.permissions.operator.restrict.secret }}
- apiGroups:
- ""
resources:
- external
- pods
{{- if eq .Values.permissions.operator.restrict.secret false }}
resources:
- secrets
{{- end }}
- services
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- limitranges
verbs:
- list
- watch
{{- with .Values.permissions.operator.restrict.namesAllowList }}
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- list
- watch
- apiGroups:
- '*'
resources:
- '*'
- secrets
verbs:
- get
resourceNames: {{ toYaml . | nindent 4 }}
{{- end }}
{{- end }}

{{- if .Values.rbac.enabledCustomScaledRefKinds }}
{{- if not .Values.rbac.scaledRefKinds }}
- apiGroups:
- '*'
resources:
Expand All @@ -69,34 +61,40 @@ rules:
- patch
- update
- watch
{{- if and .Values.certificates.autoGenerated ( not .Values.certificates.certManager.enabled ) }}
{{- else }}
- apiGroups:
- admissionregistration.k8s.io
- apps
resources:
- validatingwebhookconfigurations
- deployments/scale
- statefulsets/scale
verbs:
- get
- list
- patch
- update
- watch
{{- range .Values.rbac.scaledRefKinds }}
- apiGroups:
- apiregistration.k8s.io
- {{ .apiGroup | quote }}
resources:
- apiservices
- {{ .kind | quote }}
- {{ printf "%s/scale" .kind | quote }}
verbs:
- get
- list
- patch
- update
- watch
{{- end }}
{{- end }}
{{- end }}
{{- end }}
- apiGroups:
- apps
resources:
- deployments
- statefulsets
verbs:
- get
- list
- watch
- apiGroups:
Expand All @@ -118,32 +116,15 @@ rules:
- cloudeventsources/status
verbs:
- '*'
- apiGroups:
- keda.sh
resources:
- clustertriggerauthentications
- clustertriggerauthentications/status
verbs:
- '*'
- apiGroups:
- keda.sh
resources:
- scaledjobs
- scaledjobs/finalizers
- scaledjobs/status
verbs:
- '*'
- apiGroups:
- keda.sh
resources:
- scaledobjects
- scaledobjects/finalizers
- scaledobjects/status
verbs:
- '*'
- apiGroups:
- keda.sh
resources:
- triggerauthentications
- triggerauthentications/status
verbs:
Expand Down
49 changes: 49 additions & 0 deletions keda/templates/manager/clusterrolebindings.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{{- if .Values.rbac.create }}
{{- if not .Values.watchNamespace }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
{{- with .Values.additionalAnnotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
labels:
app.kubernetes.io/name: {{ .Values.operator.name }}
{{- include "keda.labels" . | indent 4 }}
name: {{ .Values.operator.name }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ .Values.operator.name }}
subjects:
- kind: ServiceAccount
name: {{ (.Values.serviceAccount.operator).name | default .Values.serviceAccount.name }}
namespace: {{ .Release.Namespace }}
{{- else }}
{{- range ( split "," .Values.watchNamespace ) }}
---
# Role binding for namespace '{{ . }}'
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
{{- with $.Values.additionalAnnotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
labels:
app.kubernetes.io/name: {{ $.Values.operator.name }}
{{- include "keda.labels" $ | indent 4 }}
name: {{ $.Values.operator.name }}
namespace: {{ . | trim }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ $.Values.operator.name }}
subjects:
- kind: ServiceAccount
name: {{ ($.Values.serviceAccount.operator).name | default $.Values.serviceAccount.name }}
namespace: {{ $.Release.Namespace }}
---
{{- end }}
{{- end }}
{{- end }}
7 changes: 5 additions & 2 deletions keda/templates/manager/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ spec:
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ .Values.serviceAccount.name }}
automountServiceAccountToken: true
serviceAccountName: {{ (.Values.serviceAccount.operator).name | default .Values.serviceAccount.name }}
automountServiceAccountToken: {{ (.Values.serviceAccount.operator).automountServiceAccountToken | default .Values.serviceAccount.automountServiceAccountToken }}
securityContext:
{{- if .Values.podSecurityContext.operator }}
{{- toYaml .Values.podSecurityContext.operator | nindent 8 }}
Expand Down Expand Up @@ -85,6 +85,9 @@ spec:
- "--zap-log-level={{ .Values.logging.operator.level }}"
- "--zap-encoder={{ .Values.logging.operator.format }}"
- "--zap-time-encoding={{ .Values.logging.operator.timeEncoding }}"
{{- if .Values.logging.operator.stackTracesEnabled }}
- "--zap-stacktrace-level=error"
{{- end }}
- "--cert-dir={{ .Values.certificates.mountPath }}"
- "--enable-cert-rotation={{ and .Values.certificates.autoGenerated ( not .Values.certificates.certManager.enabled ) }}"
- "--cert-secret-name={{ .Values.certificates.secretName }}"
Expand Down
Loading

0 comments on commit 42ce6e9

Please sign in to comment.