Repository: kumahq/kuma
Pull request #13445 (2025-04-23 12:10:40)

Revert "ci(ipv6): disable kind ip v6 because of a kernel bug (#13392)"
This reverts commit 5f96a0a5453bc177d2249584bb9ba56d30f3be5e.

## Motivation

According to https://github.com/actions/runner-images/issues/11985#issuecomment-2823503856 this should be resolved now

github-actions[bot]: ## Reviewer Checklist
:mag: Each of these sections need to be checked by the reviewer of the PR :mag::
If something doesn't apply please check the box and add a justification if the reason is non obvious.
- [ ] Is the PR title satisfactory? Is this part of a larger feature and should be grouped using `> Changelog`?
- [ ] PR description is clear and complete. It [Links to relevant issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword) as well as docs and UI issues
- [ ] This will not break child repos: it doesn't hardcode values (.e.g "kumahq" as an image registry)
- [ ] IPv6 is taken into account (.e.g: no string concatenation of host port)
- [ ] Tests (Unit test, E2E tests, manual test on universal and k8s)
    - Don't forget `ci/` labels to run additional/fewer tests
- [ ] Does this contain a change that needs to be notified to users? In this case, [`UPGRADE.md`](../blob/master/UPGRADE.md) should be updated.
- [ ] Does it need to be backported according to the [backporting policy](../blob/master/CONTRIBUTING.md#backporting)? ([this](https://github.com/kumahq/kuma/actions/workflows/auto-backport.yaml) GH action will add "backport" label based on these [file globs](https://github.com/kumahq/kuma/blob/master/.github/workflows/auto-backport.yaml#L6), if you want to prevent it from adding the "backport" label use [no-backport-autolabel](https://github.com/kumahq/kuma/blob/master/.github/workflows/auto-backport.yaml#L8) label)
<!-- Sticky Pull Request CommentPR reviewer checklist -->

Patch:
diff --git a/UPGRADE.md b/UPGRADE.md
index 158c27b0b..d0bfc01c8 100644
--- a/UPGRADE.md
+++ b/UPGRADE.md
@@ -26,6 +26,15 @@ If you are running helm with `noHelmHooks` please set label on the system namesp
 kubectl label namespace SYSTEM_NAMESPACE kuma.io/sidecar-injection=disabled
 ```
 
+### More Restricted `ClusterRole` for Control Plane and CNI
+
+We have split the `ClusterRole` for the control plane into two parts:
+
+* A cluster-scoped `ClusterRole` with read access to namespaced resources.
+* A `ClusterRole` with write permissions, now scoped more narrowly.
+
+By default, a `ClusterRoleBinding` is used to grant write permissions to the control plane, and no action is required from the user. However, if you want the control plane to have access only in specific namespaces, you can use the `enabledNamespaces` configuration to define where it should have write permissions.
+
 ### Namespaces that are part of the Mesh requires `kuma.io/sidecar-injection` label to exist
 
 Since version 2.11.x, to improve performance and security, each namespace participating in the Mesh is required to have the `kuma.io/sidecar-injection` label set.
diff --git a/deployments/charts/kuma/README.md b/deployments/charts/kuma/README.md
index 1c07c9fd1..2a7d005ff 100644
--- a/deployments/charts/kuma/README.md
+++ b/deployments/charts/kuma/README.md
@@ -17,6 +17,7 @@ A Helm chart for the Kuma Control Plane
 | installCrdsOnUpgrade.enabled | bool | `true` | Whether install new CRDs before upgrade (if any were introduced with the new version of Kuma) |
 | installCrdsOnUpgrade.imagePullSecrets | list | `[]` | The `imagePullSecrets` to attach to the Service Account running CRD installation. This field will be deprecated in a future release, please use .global.imagePullSecrets |
 | noHelmHooks | bool | `false` | Whether to disable all helm hooks |
+| enabledNamespaces | list | `[]` | Namespaces that are part of the Mesh. When specified, the control plane receives write permissions only for the listed namespaces. If not specified, the control plane has write permissions for all namespaces. |
 | restartOnSecretChange | bool | `true` | Whether to restart control-plane by calculating a new checksum for the secret |
 | controlPlane.environment | string | `"kubernetes"` | Environment that control plane is run in, useful when running universal global control plane on k8s |
 | controlPlane.extraLabels | object | `{}` | Labels to add to resources in addition to default labels |
@@ -115,6 +116,7 @@ A Helm chart for the Kuma Control Plane
 | cni.podAnnotations | object | `{}` | Additional pod annotations |
 | cni.namespace | string | `"kube-system"` | Set the CNI namespace |
 | cni.affinity | object | `{}` | Set the CNI affinity |
+| cni.taintController.enabled | bool | `true` | Enable taint controller |
 | cni.image.repository | string | `"kuma-cni"` | CNI image repository |
 | cni.image.tag | string | `nil` | CNI image tag - defaults to .Chart.AppVersion |
 | cni.image.imagePullPolicy | string | `"IfNotPresent"` | CNI image pull policy |
diff --git a/deployments/charts/kuma/templates/_helpers.tpl b/deployments/charts/kuma/templates/_helpers.tpl
index 63a37c2de..e3dc5ed47 100644
--- a/deployments/charts/kuma/templates/_helpers.tpl
+++ b/deployments/charts/kuma/templates/_helpers.tpl
@@ -307,7 +307,7 @@ env:
 - name: KUMA_EXPERIMENTAL_SIDECAR_CONTAINERS
   value: "true"
 {{- end }}
-{{- if .Values.cni.enabled }}
+{{- if and .Values.cni.enabled .Values.cni.taintController.enabled }}
 - name: KUMA_RUNTIME_KUBERNETES_NODE_TAINT_CONTROLLER_ENABLED
   value: "true"
 - name: KUMA_RUNTIME_KUBERNETES_NODE_TAINT_CONTROLLER_CNI_APP
diff --git a/deployments/charts/kuma/templates/cni-rbac.yaml b/deployments/charts/kuma/templates/cni-rbac.yaml
index 07af2b215..6135aef85 100644
--- a/deployments/charts/kuma/templates/cni-rbac.yaml
+++ b/deployments/charts/kuma/templates/cni-rbac.yaml
@@ -19,11 +19,6 @@ metadata:
   labels:
   {{ include "kuma.cniLabels" . | nindent 4 }}
 rules:
-  - apiGroups: [""]
-    resources:
-      - nodes
-    verbs:
-      - get
   - apiGroups: [""]
     resources:
       - pods
@@ -33,6 +28,26 @@ rules:
       - list
       - watch
       {{- end }}
+{{- if gt (len .Values.enabledNamespaces) 0 }}
+{{- $root := . }}
+{{- range $element := .Values.enabledNamespaces }}
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: {{ include "kuma.name" $root }}-cni
+  labels: {{ include "kuma.cpLabels" $root | nindent 4 }}
+  namespace: {{ $element }}
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: {{ include "kuma.name" $root }}-cni
+subjects:
+  - kind: ServiceAccount
+    name: {{ include "kuma.name" $root }}-cni
+    namespace: {{ $root.Release.Namespace }}
+{{- end }}
+{{- else }}
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -48,4 +63,5 @@ subjects:
   - kind: ServiceAccount
     name: {{ include "kuma.name" . }}-cni
     namespace: {{ .Values.cni.namespace }}
-  {{- end }}
+{{- end }}
+{{- end }}
diff --git a/deployments/charts/kuma/templates/cp-rbac.yaml b/deployments/charts/kuma/templates/cp-rbac.yaml
index e9c511fe4..a4bff0957 100644
--- a/deployments/charts/kuma/templates/cp-rbac.yaml
+++ b/deployments/charts/kuma/templates/cp-rbac.yaml
@@ -22,42 +22,37 @@ metadata:
   name: {{ include "kuma.name" . }}-control-plane
   labels: {{ include "kuma.cpLabels" . | nindent 4 }}
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
 {{- if .Values.controlPlane.supportGatewaySecretsInAllNamespaces }}
       - secrets
-{{- end }}
-{{- if and .Values.transparentProxy.configMap.enabled .Values.transparentProxy.configMap.config }}
-      - configmaps
 {{- end }}
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -67,70 +62,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -192,14 +153,6 @@ rules:
       - get
       - patch
       - update
-  - apiGroups:
-      - ""
-    resources:
-      - pods/finalizers
-    verbs:
-      - get
-      - patch
-      - update
   {{- if .Values.cni.enabled }}
   - apiGroups:
       - k8s.cni.cncf.io
@@ -209,8 +162,6 @@ rules:
       - get
       - list
       - watch
-      - create
-      - delete
   - apiGroups:
       - apiextensions.k8s.io
     resources:
@@ -219,18 +170,14 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  {{- if.Values.cni.taintController.enabled }}
+  - apiGroups: # required for taint controller
       - ""
     resources:
       - nodes
     verbs:
       - update
-  - apiGroups:
-      - "pods"
-    resources:
-      - pods
-    verbs:
-      - list
+  {{- end }}
   {{- end }}
   # validate k8s token before issuing mTLS cert
   - apiGroups:
@@ -262,9 +209,9 @@ metadata:
   labels: {{ include "kuma.cpLabels" . | nindent 4 }}
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -277,14 +224,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -292,6 +247,41 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
+  {{- if .Values.cni.enabled }}
+  - apiGroups:
+      - k8s.cni.cncf.io
+    resources:
+      - network-attachment-definitions
+    verbs:
+      - get
+      - list
+      - watch
+      - create
+      - delete
+  {{- end }}
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
@@ -307,4 +297,130 @@ subjects:
   - kind: ServiceAccount
     name: {{ include "kuma.name" . }}-control-plane
     namespace: {{ .Release.Namespace }}
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: {{ include "kuma.name" . }}-control-plane-writer
+  labels: {{ include "kuma.cpLabels" . | nindent 4 }}
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+    # required by MeshGateway
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
+  - apiGroups:
+      - ""
+    resources:
+      - pods/finalizers
+    verbs:
+      - get
+      - patch
+      - update
+  - apiGroups:
+    # Gateway API
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
+  {{- if .Values.cni.enabled }}
+  - apiGroups:
+      - k8s.cni.cncf.io
+    resources:
+      - network-attachment-definitions
+    verbs:
+      - create
+      - delete
+  {{- end }}
+{{- if gt (len .Values.enabledNamespaces) 0 }}
+{{- $root := . }}
+{{- range $element := .Values.enabledNamespaces }}
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: {{ include "kuma.name" $root }}-control-plane-writer
+  labels: {{ include "kuma.cpLabels" $root | nindent 4 }}
+  namespace: {{ $element }}
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: {{ include "kuma.name" $root }}-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: {{ include "kuma.name" $root }}-control-plane
+    namespace: {{ $root.Release.Namespace }}
+{{- end }}
+{{- end }}
+{{- if eq (len .Values.enabledNamespaces) 0 }}
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: {{ include "kuma.name" . }}-control-plane-writer
+  labels: {{ include "kuma.cpLabels" . | nindent 4 }}
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: {{ include "kuma.name" . }}-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: {{ include "kuma.name" . }}-control-plane
+    namespace: {{ .Release.Namespace }}
+{{- end }}
 {{- end }}
diff --git a/deployments/charts/kuma/values.yaml b/deployments/charts/kuma/values.yaml
index 49397b078..a235e3164 100644
--- a/deployments/charts/kuma/values.yaml
+++ b/deployments/charts/kuma/values.yaml
@@ -20,6 +20,10 @@ installCrdsOnUpgrade:
 # -- Whether to disable all helm hooks
 noHelmHooks: false
 
+# -- Namespaces that are part of the Mesh. When specified, the control plane receives write permissions only for the listed namespaces.
+# If not specified, the control plane has write permissions for all namespaces.
+enabledNamespaces: []
+
 # -- Whether to restart control-plane by calculating a new checksum for the secret
 restartOnSecretChange: true
 
@@ -377,6 +381,10 @@ cni:
   # -- Set the CNI affinity
   affinity: {}
 
+  taintController:
+    # -- Enable taint controller
+    enabled: true
+
   image:
     # -- CNI image repository
     repository: "kuma-cni"
diff --git a/docs/generated/raw/helm-values.yaml b/docs/generated/raw/helm-values.yaml
index 49397b078..a235e3164 100644
--- a/docs/generated/raw/helm-values.yaml
+++ b/docs/generated/raw/helm-values.yaml
@@ -20,6 +20,10 @@ installCrdsOnUpgrade:
 # -- Whether to disable all helm hooks
 noHelmHooks: false
 
+# -- Namespaces that are part of the Mesh. When specified, the control plane receives write permissions only for the listed namespaces.
+# If not specified, the control plane has write permissions for all namespaces.
+enabledNamespaces: []
+
 # -- Whether to restart control-plane by calculating a new checksum for the secret
 restartOnSecretChange: true
 
@@ -377,6 +381,10 @@ cni:
   # -- Set the CNI affinity
   affinity: {}
 
+  taintController:
+    # -- Enable taint controller
+    enabled: true
+
   image:
     # -- CNI image repository
     repository: "kuma-cni"


Test patch:
diff --git a/.github/workflows/_e2e.yaml b/.github/workflows/_e2e.yaml
index d04d67d01..5f9582f4c 100644
--- a/.github/workflows/_e2e.yaml
+++ b/.github/workflows/_e2e.yaml
@@ -23,8 +23,7 @@ jobs:
     timeout-minutes: 60
     # can't use env vars here
     runs-on: ${{ inputs.runner }}
-    # workaround for this bug https://github.com/actions/runner-images/issues/11985 - revert when done
-    if: ${{ fromJSON(inputs.matrix).k8sVersion != 'kindipv6' && inputs.runner != '' }}
+    if: ${{ inputs.runner != '' }}
     strategy:
       fail-fast: false
       matrix:
diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.cni-enabled.golden.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.cni-enabled.golden.yaml
index 1935574b8..c647d87fb 100644
--- a/app/kumactl/cmd/install/testdata/install-control-plane.cni-enabled.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-control-plane.cni-enabled.golden.yaml
@@ -76,11 +76,6 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
-  - apiGroups: [""]
-    resources:
-      - nodes
-    verbs:
-      - get
   - apiGroups: [""]
     resources:
       - pods
@@ -96,36 +91,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -135,70 +128,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -271,50 +230,125 @@ rules:
       - patch
       - update
   - apiGroups:
+      - k8s.cni.cncf.io
+    resources:
+      - network-attachment-definitions
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+      - apiextensions.k8s.io
+    resources:
+      - customresourcedefinitions
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups: # required for taint controller
       - ""
     resources:
-      - pods/finalizers
+      - nodes
+    verbs:
+      - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
     verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
+      - watch
   - apiGroups:
-      - k8s.cni.cncf.io
+      - "batch"
     resources:
-      - network-attachment-definitions
+      - jobs
     verbs:
       - get
       - list
       - watch
-      - create
-      - delete
   - apiGroups:
-      - apiextensions.k8s.io
+    # required by MeshGateway
+      - ""
     resources:
-      - customresourcedefinitions
+      - services
     verbs:
       - get
+      - delete
       - list
       - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
-      - nodes
+      - pods/finalizers
     verbs:
+      - get
+      - patch
       - update
   - apiGroups:
-      - "pods"
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - pods
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
+      - create
+      - delete
+      - get
       - list
-  # validate k8s token before issuing mTLS cert
+      - patch
+      - update
+      - watch
   - apiGroups:
-      - authentication.k8s.io
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
+  - apiGroups:
+      - k8s.cni.cncf.io
+    resources:
+      - network-attachment-definitions
     verbs:
       - create
+      - delete
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -352,6 +386,23 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -362,9 +413,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -377,14 +428,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -392,6 +451,39 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
+  - apiGroups:
+      - k8s.cni.cncf.io
+    resources:
+      - network-attachment-definitions
+    verbs:
+      - get
+      - list
+      - watch
+      - create
+      - delete
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.defaults.golden.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.defaults.golden.yaml
index 523f9bb28..f49162dbc 100644
--- a/app/kumactl/cmd/install/testdata/install-control-plane.defaults.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-control-plane.defaults.golden.yaml
@@ -10444,36 +10444,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -10483,70 +10481,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -10618,6 +10582,65 @@ rules:
       - get
       - patch
       - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+    # required by MeshGateway
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
@@ -10626,13 +10649,30 @@ rules:
       - get
       - patch
       - update
-  # validate k8s token before issuing mTLS cert
   - apiGroups:
-      - authentication.k8s.io
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
       - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -10652,6 +10692,23 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -10662,9 +10719,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -10677,14 +10734,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -10692,6 +10757,29 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.dump-values.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.dump-values.yaml
index 49397b078..a235e3164 100644
--- a/app/kumactl/cmd/install/testdata/install-control-plane.dump-values.yaml
+++ b/app/kumactl/cmd/install/testdata/install-control-plane.dump-values.yaml
@@ -20,6 +20,10 @@ installCrdsOnUpgrade:
 # -- Whether to disable all helm hooks
 noHelmHooks: false
 
+# -- Namespaces that are part of the Mesh. When specified, the control plane receives write permissions only for the listed namespaces.
+# If not specified, the control plane has write permissions for all namespaces.
+enabledNamespaces: []
+
 # -- Whether to restart control-plane by calculating a new checksum for the secret
 restartOnSecretChange: true
 
@@ -377,6 +381,10 @@ cni:
   # -- Set the CNI affinity
   affinity: {}
 
+  taintController:
+    # -- Enable taint controller
+    enabled: true
+
   image:
     # -- CNI image repository
     repository: "kuma-cni"
diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.gateway-api-present.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.gateway-api-present.yaml
index 07be82585..b0f83343a 100644
--- a/app/kumactl/cmd/install/testdata/install-control-plane.gateway-api-present.yaml
+++ b/app/kumactl/cmd/install/testdata/install-control-plane.gateway-api-present.yaml
@@ -10444,36 +10444,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -10483,70 +10481,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -10618,6 +10582,65 @@ rules:
       - get
       - patch
       - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+    # required by MeshGateway
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
@@ -10626,13 +10649,30 @@ rules:
       - get
       - patch
       - update
-  # validate k8s token before issuing mTLS cert
   - apiGroups:
-      - authentication.k8s.io
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
       - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -10652,6 +10692,23 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -10662,9 +10719,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -10677,14 +10734,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -10692,6 +10757,29 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.global.golden.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.global.golden.yaml
index 2ec2dabbc..3ef862986 100644
--- a/app/kumactl/cmd/install/testdata/install-control-plane.global.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-control-plane.global.golden.yaml
@@ -41,36 +41,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -80,70 +78,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -215,6 +179,65 @@ rules:
       - get
       - patch
       - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+    # required by MeshGateway
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
@@ -223,13 +246,30 @@ rules:
       - get
       - patch
       - update
-  # validate k8s token before issuing mTLS cert
   - apiGroups:
-      - authentication.k8s.io
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
       - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -249,6 +289,23 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -259,9 +316,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -274,14 +331,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -289,6 +354,29 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.override-env-vars.golden.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.override-env-vars.golden.yaml
index ab68645c5..3ef37fc0c 100644
--- a/app/kumactl/cmd/install/testdata/install-control-plane.override-env-vars.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-control-plane.override-env-vars.golden.yaml
@@ -41,36 +41,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -80,70 +78,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -215,6 +179,65 @@ rules:
       - get
       - patch
       - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+    # required by MeshGateway
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
@@ -223,13 +246,30 @@ rules:
       - get
       - patch
       - update
-  # validate k8s token before issuing mTLS cert
   - apiGroups:
-      - authentication.k8s.io
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
       - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -249,6 +289,23 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -259,9 +316,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -274,14 +331,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -289,6 +354,29 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.overrides.golden.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.overrides.golden.yaml
index e22909292..277064992 100644
--- a/app/kumactl/cmd/install/testdata/install-control-plane.overrides.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-control-plane.overrides.golden.yaml
@@ -41,36 +41,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -80,70 +78,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -215,6 +179,65 @@ rules:
       - get
       - patch
       - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+    # required by MeshGateway
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
@@ -223,13 +246,30 @@ rules:
       - get
       - patch
       - update
-  # validate k8s token before issuing mTLS cert
   - apiGroups:
-      - authentication.k8s.io
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
       - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -249,6 +289,23 @@ subjects:
     namespace: kuma
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -259,9 +316,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -274,14 +331,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -289,6 +354,29 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.registry.golden.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.registry.golden.yaml
index 89f33705e..12e55328c 100644
--- a/app/kumactl/cmd/install/testdata/install-control-plane.registry.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-control-plane.registry.golden.yaml
@@ -41,36 +41,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -80,70 +78,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -215,6 +179,65 @@ rules:
       - get
       - patch
       - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+    # required by MeshGateway
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
@@ -223,13 +246,30 @@ rules:
       - get
       - patch
       - update
-  # validate k8s token before issuing mTLS cert
   - apiGroups:
-      - authentication.k8s.io
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
       - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -249,6 +289,23 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -259,9 +316,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -274,14 +331,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -289,6 +354,29 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.tproxy-ebpf-experimental-enabled.golden.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.tproxy-ebpf-experimental-enabled.golden.yaml
index 261870d3a..a27ba7712 100644
--- a/app/kumactl/cmd/install/testdata/install-control-plane.tproxy-ebpf-experimental-enabled.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-control-plane.tproxy-ebpf-experimental-enabled.golden.yaml
@@ -41,36 +41,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -80,70 +78,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -215,6 +179,65 @@ rules:
       - get
       - patch
       - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+    # required by MeshGateway
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
@@ -223,13 +246,30 @@ rules:
       - get
       - patch
       - update
-  # validate k8s token before issuing mTLS cert
   - apiGroups:
-      - authentication.k8s.io
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
       - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -249,6 +289,23 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -259,9 +316,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -274,14 +331,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -289,6 +354,29 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.with-egress.golden.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.with-egress.golden.yaml
index 798504dc1..c720cc412 100644
--- a/app/kumactl/cmd/install/testdata/install-control-plane.with-egress.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-control-plane.with-egress.golden.yaml
@@ -51,36 +51,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -90,70 +88,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -225,6 +189,65 @@ rules:
       - get
       - patch
       - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+    # required by MeshGateway
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
@@ -233,13 +256,30 @@ rules:
       - get
       - patch
       - update
-  # validate k8s token before issuing mTLS cert
   - apiGroups:
-      - authentication.k8s.io
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
       - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -259,6 +299,23 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -269,9 +326,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -284,14 +341,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -299,6 +364,29 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.with-helm-set.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.with-helm-set.yaml
index 02de19f07..f802e12db 100644
--- a/app/kumactl/cmd/install/testdata/install-control-plane.with-helm-set.yaml
+++ b/app/kumactl/cmd/install/testdata/install-control-plane.with-helm-set.yaml
@@ -10464,36 +10464,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -10503,70 +10501,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -10638,6 +10602,65 @@ rules:
       - get
       - patch
       - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+    # required by MeshGateway
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
@@ -10646,13 +10669,30 @@ rules:
       - get
       - patch
       - update
-  # validate k8s token before issuing mTLS cert
   - apiGroups:
-      - authentication.k8s.io
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
       - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -10672,6 +10712,23 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -10682,9 +10739,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -10697,14 +10754,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -10712,6 +10777,29 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.with-helm-values.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.with-helm-values.yaml
index 55934ee93..06d5df346 100644
--- a/app/kumactl/cmd/install/testdata/install-control-plane.with-helm-values.yaml
+++ b/app/kumactl/cmd/install/testdata/install-control-plane.with-helm-values.yaml
@@ -41,36 +41,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -80,70 +78,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -215,6 +179,65 @@ rules:
       - get
       - patch
       - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+    # required by MeshGateway
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
@@ -223,13 +246,30 @@ rules:
       - get
       - patch
       - update
-  # validate k8s token before issuing mTLS cert
   - apiGroups:
-      - authentication.k8s.io
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
       - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -249,6 +289,23 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -259,9 +316,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -274,14 +331,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -289,6 +354,29 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.with-ingress.golden.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.with-ingress.golden.yaml
index 72e30c281..033233f0c 100644
--- a/app/kumactl/cmd/install/testdata/install-control-plane.with-ingress.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-control-plane.with-ingress.golden.yaml
@@ -51,36 +51,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -90,70 +88,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -225,6 +189,65 @@ rules:
       - get
       - patch
       - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+    # required by MeshGateway
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
@@ -233,13 +256,30 @@ rules:
       - get
       - patch
       - update
-  # validate k8s token before issuing mTLS cert
   - apiGroups:
-      - authentication.k8s.io
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
       - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -259,6 +299,23 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -269,9 +326,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -284,14 +341,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -299,6 +364,29 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-control-plane.zone.golden.yaml b/app/kumactl/cmd/install/testdata/install-control-plane.zone.golden.yaml
index 775370e79..c94d043bb 100644
--- a/app/kumactl/cmd/install/testdata/install-control-plane.zone.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-control-plane.zone.golden.yaml
@@ -41,36 +41,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -80,70 +78,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -215,6 +179,65 @@ rules:
       - get
       - patch
       - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+    # required by MeshGateway
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
@@ -223,13 +246,30 @@ rules:
       - get
       - patch
       - update
-  # validate k8s token before issuing mTLS cert
   - apiGroups:
-      - authentication.k8s.io
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
       - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -249,6 +289,23 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -259,9 +316,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -274,14 +331,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -289,6 +354,29 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-cp-helm/dnsConfigOption.golden.yaml b/app/kumactl/cmd/install/testdata/install-cp-helm/dnsConfigOption.golden.yaml
index b7f8f8103..e2b4c114f 100644
--- a/app/kumactl/cmd/install/testdata/install-cp-helm/dnsConfigOption.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-cp-helm/dnsConfigOption.golden.yaml
@@ -61,36 +61,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -100,70 +98,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -235,6 +199,65 @@ rules:
       - get
       - patch
       - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+    # required by MeshGateway
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
@@ -243,13 +266,30 @@ rules:
       - get
       - patch
       - update
-  # validate k8s token before issuing mTLS cert
   - apiGroups:
-      - authentication.k8s.io
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
       - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -269,6 +309,23 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -279,9 +336,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -294,14 +351,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -309,6 +374,29 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-cp-helm/doNotChangeTlsChecksum.golden.yaml b/app/kumactl/cmd/install/testdata/install-cp-helm/doNotChangeTlsChecksum.golden.yaml
index 6bb188d94..90922a343 100644
--- a/app/kumactl/cmd/install/testdata/install-cp-helm/doNotChangeTlsChecksum.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-cp-helm/doNotChangeTlsChecksum.golden.yaml
@@ -41,36 +41,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -80,70 +78,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -215,6 +179,65 @@ rules:
       - get
       - patch
       - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+    # required by MeshGateway
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
@@ -223,13 +246,30 @@ rules:
       - get
       - patch
       - update
-  # validate k8s token before issuing mTLS cert
   - apiGroups:
-      - authentication.k8s.io
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
       - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -249,6 +289,23 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -259,9 +316,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -274,14 +331,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -289,6 +354,29 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-cp-helm/empty.golden.yaml b/app/kumactl/cmd/install/testdata/install-cp-helm/empty.golden.yaml
index 65473499c..24b1a2b73 100644
--- a/app/kumactl/cmd/install/testdata/install-cp-helm/empty.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-cp-helm/empty.golden.yaml
@@ -41,36 +41,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -80,70 +78,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -215,6 +179,65 @@ rules:
       - get
       - patch
       - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+    # required by MeshGateway
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
@@ -223,13 +246,30 @@ rules:
       - get
       - patch
       - update
-  # validate k8s token before issuing mTLS cert
   - apiGroups:
-      - authentication.k8s.io
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
       - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -249,6 +289,23 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -259,9 +316,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -274,14 +331,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -289,6 +354,29 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-cp-helm/envVarsDownwardApi.golden.yaml b/app/kumactl/cmd/install/testdata/install-cp-helm/envVarsDownwardApi.golden.yaml
index d17390198..ed19e6a91 100644
--- a/app/kumactl/cmd/install/testdata/install-cp-helm/envVarsDownwardApi.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-cp-helm/envVarsDownwardApi.golden.yaml
@@ -41,36 +41,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -80,70 +78,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -215,6 +179,65 @@ rules:
       - get
       - patch
       - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+    # required by MeshGateway
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
@@ -223,13 +246,30 @@ rules:
       - get
       - patch
       - update
-  # validate k8s token before issuing mTLS cert
   - apiGroups:
-      - authentication.k8s.io
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
       - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -249,6 +289,23 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -259,9 +316,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -274,14 +331,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -289,6 +354,29 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-cp-helm/fix12847.golden.yaml b/app/kumactl/cmd/install/testdata/install-cp-helm/fix12847.golden.yaml
index 999adc670..51527ad85 100644
--- a/app/kumactl/cmd/install/testdata/install-cp-helm/fix12847.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-cp-helm/fix12847.golden.yaml
@@ -76,11 +76,6 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
-  - apiGroups: [""]
-    resources:
-      - nodes
-    verbs:
-      - get
   - apiGroups: [""]
     resources:
       - pods
@@ -96,36 +91,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -135,70 +128,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -271,50 +230,125 @@ rules:
       - patch
       - update
   - apiGroups:
+      - k8s.cni.cncf.io
+    resources:
+      - network-attachment-definitions
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+      - apiextensions.k8s.io
+    resources:
+      - customresourcedefinitions
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups: # required for taint controller
       - ""
     resources:
-      - pods/finalizers
+      - nodes
+    verbs:
+      - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
     verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
+      - watch
   - apiGroups:
-      - k8s.cni.cncf.io
+      - "batch"
     resources:
-      - network-attachment-definitions
+      - jobs
     verbs:
       - get
       - list
       - watch
-      - create
-      - delete
   - apiGroups:
-      - apiextensions.k8s.io
+    # required by MeshGateway
+      - ""
     resources:
-      - customresourcedefinitions
+      - services
     verbs:
       - get
+      - delete
       - list
       - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
-      - nodes
+      - pods/finalizers
     verbs:
+      - get
+      - patch
       - update
   - apiGroups:
-      - "pods"
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - pods
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
+      - create
+      - delete
+      - get
       - list
-  # validate k8s token before issuing mTLS cert
+      - patch
+      - update
+      - watch
   - apiGroups:
-      - authentication.k8s.io
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
+  - apiGroups:
+      - k8s.cni.cncf.io
+    resources:
+      - network-attachment-definitions
     verbs:
       - create
+      - delete
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -352,6 +386,23 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -362,9 +413,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -377,14 +428,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -392,6 +451,39 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
+  - apiGroups:
+      - k8s.cni.cncf.io
+    resources:
+      - network-attachment-definitions
+    verbs:
+      - get
+      - list
+      - watch
+      - create
+      - delete
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-cp-helm/fix13029.golden.yaml b/app/kumactl/cmd/install/testdata/install-cp-helm/fix13029.golden.yaml
index 5a90b7442..6928bcdf3 100644
--- a/app/kumactl/cmd/install/testdata/install-cp-helm/fix13029.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-cp-helm/fix13029.golden.yaml
@@ -76,11 +76,6 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
-  - apiGroups: [""]
-    resources:
-      - nodes
-    verbs:
-      - get
   - apiGroups: [""]
     resources:
       - pods
@@ -96,36 +91,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -135,70 +128,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -271,50 +230,125 @@ rules:
       - patch
       - update
   - apiGroups:
+      - k8s.cni.cncf.io
+    resources:
+      - network-attachment-definitions
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+      - apiextensions.k8s.io
+    resources:
+      - customresourcedefinitions
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups: # required for taint controller
       - ""
     resources:
-      - pods/finalizers
+      - nodes
+    verbs:
+      - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
     verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
+      - watch
   - apiGroups:
-      - k8s.cni.cncf.io
+      - "batch"
     resources:
-      - network-attachment-definitions
+      - jobs
     verbs:
       - get
       - list
       - watch
-      - create
-      - delete
   - apiGroups:
-      - apiextensions.k8s.io
+    # required by MeshGateway
+      - ""
     resources:
-      - customresourcedefinitions
+      - services
     verbs:
       - get
+      - delete
       - list
       - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
-      - nodes
+      - pods/finalizers
     verbs:
+      - get
+      - patch
       - update
   - apiGroups:
-      - "pods"
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - pods
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
+      - create
+      - delete
+      - get
       - list
-  # validate k8s token before issuing mTLS cert
+      - patch
+      - update
+      - watch
   - apiGroups:
-      - authentication.k8s.io
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
+  - apiGroups:
+      - k8s.cni.cncf.io
+    resources:
+      - network-attachment-definitions
     verbs:
       - create
+      - delete
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -352,6 +386,23 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -362,9 +413,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -377,14 +428,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -392,6 +451,39 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
+  - apiGroups:
+      - k8s.cni.cncf.io
+    resources:
+      - network-attachment-definitions
+    verbs:
+      - get
+      - list
+      - watch
+      - create
+      - delete
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-cp-helm/fix4485.golden.yaml b/app/kumactl/cmd/install/testdata/install-cp-helm/fix4485.golden.yaml
index 5d0d371a7..1fa484b66 100644
--- a/app/kumactl/cmd/install/testdata/install-cp-helm/fix4485.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-cp-helm/fix4485.golden.yaml
@@ -58,36 +58,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -97,70 +95,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -232,6 +196,66 @@ rules:
       - get
       - patch
       - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    "foo": "baz"
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+    # required by MeshGateway
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
@@ -240,13 +264,30 @@ rules:
       - get
       - patch
       - update
-  # validate k8s token before issuing mTLS cert
   - apiGroups:
-      - authentication.k8s.io
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
       - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -267,6 +308,24 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    "foo": "baz"
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -278,9 +337,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -293,14 +352,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -308,6 +375,29 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-cp-helm/fix4496.golden.yaml b/app/kumactl/cmd/install/testdata/install-cp-helm/fix4496.golden.yaml
index ce267abea..01258221a 100644
--- a/app/kumactl/cmd/install/testdata/install-cp-helm/fix4496.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-cp-helm/fix4496.golden.yaml
@@ -55,36 +55,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -94,70 +92,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -229,6 +193,66 @@ rules:
       - get
       - patch
       - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    "foo": "bar"
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+    # required by MeshGateway
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
@@ -237,13 +261,30 @@ rules:
       - get
       - patch
       - update
-  # validate k8s token before issuing mTLS cert
   - apiGroups:
-      - authentication.k8s.io
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
       - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -264,6 +305,24 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    "foo": "bar"
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -275,9 +334,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -290,14 +349,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -305,6 +372,29 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-cp-helm/fix4935.golden.yaml b/app/kumactl/cmd/install/testdata/install-cp-helm/fix4935.golden.yaml
index d94966150..374828f2b 100644
--- a/app/kumactl/cmd/install/testdata/install-cp-helm/fix4935.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-cp-helm/fix4935.golden.yaml
@@ -96,11 +96,6 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
-  - apiGroups: [""]
-    resources:
-      - nodes
-    verbs:
-      - get
   - apiGroups: [""]
     resources:
       - pods
@@ -116,36 +111,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -155,70 +148,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -291,50 +250,125 @@ rules:
       - patch
       - update
   - apiGroups:
+      - k8s.cni.cncf.io
+    resources:
+      - network-attachment-definitions
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+      - apiextensions.k8s.io
+    resources:
+      - customresourcedefinitions
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups: # required for taint controller
       - ""
     resources:
-      - pods/finalizers
+      - nodes
+    verbs:
+      - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
     verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
+      - watch
   - apiGroups:
-      - k8s.cni.cncf.io
+      - "batch"
     resources:
-      - network-attachment-definitions
+      - jobs
     verbs:
       - get
       - list
       - watch
-      - create
-      - delete
   - apiGroups:
-      - apiextensions.k8s.io
+    # required by MeshGateway
+      - ""
     resources:
-      - customresourcedefinitions
+      - services
     verbs:
       - get
+      - delete
       - list
       - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
-      - nodes
+      - pods/finalizers
     verbs:
+      - get
+      - patch
       - update
   - apiGroups:
-      - "pods"
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - pods
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
+      - create
+      - delete
+      - get
       - list
-  # validate k8s token before issuing mTLS cert
+      - patch
+      - update
+      - watch
   - apiGroups:
-      - authentication.k8s.io
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
+  - apiGroups:
+      - k8s.cni.cncf.io
+    resources:
+      - network-attachment-definitions
     verbs:
       - create
+      - delete
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -372,6 +406,23 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -382,9 +433,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -397,14 +448,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -412,6 +471,39 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
+  - apiGroups:
+      - k8s.cni.cncf.io
+    resources:
+      - network-attachment-definitions
+    verbs:
+      - get
+      - list
+      - watch
+      - create
+      - delete
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-cp-helm/fix5978.golden.yaml b/app/kumactl/cmd/install/testdata/install-cp-helm/fix5978.golden.yaml
index e86b6d457..3a65e0fcc 100644
--- a/app/kumactl/cmd/install/testdata/install-cp-helm/fix5978.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-cp-helm/fix5978.golden.yaml
@@ -61,36 +61,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -100,70 +98,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -235,6 +199,65 @@ rules:
       - get
       - patch
       - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+    # required by MeshGateway
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
@@ -243,13 +266,30 @@ rules:
       - get
       - patch
       - update
-  # validate k8s token before issuing mTLS cert
   - apiGroups:
-      - authentication.k8s.io
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
       - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -269,6 +309,23 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -279,9 +336,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -294,14 +351,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -309,6 +374,29 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-cp-helm/fix7724.golden.yaml b/app/kumactl/cmd/install/testdata/install-cp-helm/fix7724.golden.yaml
index 9fccddd92..3bc83b8ee 100644
--- a/app/kumactl/cmd/install/testdata/install-cp-helm/fix7724.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-cp-helm/fix7724.golden.yaml
@@ -44,36 +44,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -83,70 +81,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -218,6 +182,65 @@ rules:
       - get
       - patch
       - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+    # required by MeshGateway
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
@@ -226,13 +249,30 @@ rules:
       - get
       - patch
       - update
-  # validate k8s token before issuing mTLS cert
   - apiGroups:
-      - authentication.k8s.io
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
       - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -252,6 +292,23 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -262,9 +319,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -277,14 +334,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -292,6 +357,29 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-cp-helm/fix7824.golden.yaml b/app/kumactl/cmd/install/testdata/install-cp-helm/fix7824.golden.yaml
index 73daa9bee..c39a389d5 100644
--- a/app/kumactl/cmd/install/testdata/install-cp-helm/fix7824.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-cp-helm/fix7824.golden.yaml
@@ -76,36 +76,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -115,70 +113,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -250,6 +214,65 @@ rules:
       - get
       - patch
       - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+    # required by MeshGateway
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
@@ -258,13 +281,30 @@ rules:
       - get
       - patch
       - update
-  # validate k8s token before issuing mTLS cert
   - apiGroups:
-      - authentication.k8s.io
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
       - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -284,6 +324,23 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -294,9 +351,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -309,14 +366,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -324,6 +389,29 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-cp-helm/minReadySeconds.golden.yaml b/app/kumactl/cmd/install/testdata/install-cp-helm/minReadySeconds.golden.yaml
index c193926ec..b730a8902 100644
--- a/app/kumactl/cmd/install/testdata/install-cp-helm/minReadySeconds.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-cp-helm/minReadySeconds.golden.yaml
@@ -41,36 +41,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -80,70 +78,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -215,6 +179,65 @@ rules:
       - get
       - patch
       - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+    # required by MeshGateway
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
@@ -223,13 +246,30 @@ rules:
       - get
       - patch
       - update
-  # validate k8s token before issuing mTLS cert
   - apiGroups:
-      - authentication.k8s.io
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
       - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -249,6 +289,23 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -259,9 +316,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -274,14 +331,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -289,6 +354,29 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
diff --git a/app/kumactl/cmd/install/testdata/install-cp-helm/roleBindingInNamespaces.golden.yaml b/app/kumactl/cmd/install/testdata/install-cp-helm/roleBindingInNamespaces.golden.yaml
new file mode 100644
index 000000000..bb929e2f1
--- /dev/null
+++ b/app/kumactl/cmd/install/testdata/install-cp-helm/roleBindingInNamespaces.golden.yaml
@@ -0,0 +1,935 @@
+
+---
+apiVersion: v1
+kind: Namespace
+metadata:
+  name: kuma-system
+  labels:
+    kuma.io/sidecar-injection: "false"
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: kuma-control-plane
+  namespace: kuma-system
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: kuma-control-plane-config
+  namespace: kuma-system
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+data:
+  config.yaml: |
+    # use this file to override default configuration of `kuma-cp`
+    #
+    # see conf/kuma-cp.conf.yml for available settings
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  # Kubernetes resources
+  - apiGroups:
+      - ""
+    resources:
+      - namespaces
+      - pods
+      - nodes
+      - services
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+      - "discovery.k8s.io"
+    resources:
+      - endpointslices
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups: # Gateway API
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gatewayclasses # ClusterScope
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gatewayclasses/status # ClusterScope
+    verbs:
+      - get
+      - patch
+      - update
+  - apiGroups:
+      - kuma.io
+    resources:
+      - dataplanes
+      - dataplaneinsights
+      - meshes
+      - zones
+      - zoneinsights
+      - zoneingresses
+      - zoneingressinsights
+      - zoneegresses
+      - zoneegressinsights
+      - meshinsights
+      - serviceinsights
+      - proxytemplates
+      - ratelimits
+      - trafficpermissions
+      - trafficroutes
+      - timeouts
+      - retries
+      - circuitbreakers
+      - virtualoutbounds
+      - containerpatches
+      - externalservices
+      - faultinjections
+      - healthchecks
+      - trafficlogs
+      - traffictraces
+      - meshgateways
+      - meshgatewayroutes
+      - meshgatewayinstances
+      - meshgatewayconfigs
+      - meshaccesslogs
+      - meshcircuitbreakers
+      - meshfaultinjections
+      - meshhealthchecks
+      - meshhttproutes
+      - meshloadbalancingstrategies
+      - meshmetrics
+      - meshpassthroughs
+      - meshproxypatches
+      - meshratelimits
+      - meshretries
+      - meshtcproutes
+      - meshtimeouts
+      - meshtlses
+      - meshtraces
+      - meshtrafficpermissions
+      - hostnamegenerators
+      - meshexternalservices
+      - meshmultizoneservices
+      - meshservices
+    verbs:
+      - get
+      - list
+      - watch
+      - create
+      - update
+      - patch
+      - delete
+  - apiGroups:
+      - kuma.io
+    resources:
+      - meshgatewayinstances/status
+      - meshgatewayinstances/finalizers
+      - meshes/finalizers
+      - dataplanes/finalizers
+    verbs:
+      - get
+      - patch
+      - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+    # required by MeshGateway
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
+  - apiGroups:
+      - ""
+    resources:
+      - pods/finalizers
+    verbs:
+      - get
+      - patch
+      - update
+  - apiGroups:
+    # Gateway API
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: kuma-control-plane
+  namespace: kuma-system
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - coordination.k8s.io
+    resources:
+      - leases
+    verbs:
+      - get
+      - list
+      - watch
+      - create
+      - update
+      - patch
+      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - configmaps
+      - secrets
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  # leader-for-life election deletes Pods in some circumstances
+  - apiGroups:
+      - ""
+    resources:
+      - pods
+    verbs:
+      - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: kuma-control-plane
+  namespace: kuma-system
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: kuma-control-plane
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+  namespace: kuma-demo
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+  namespace: kuma-test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: kuma-control-plane
+  namespace: kuma-system
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+  annotations:
+    prometheus.io/port: "5680"
+    prometheus.io/scrape: "true"
+spec:
+  type: ClusterIP
+  ports:
+    - port: 5680
+      name: diagnostics
+      appProtocol: http
+    - port: 5681
+      name: http-api-server
+      appProtocol: http
+    - port: 5682
+      name: https-api-server
+      appProtocol: https
+    - port: 443
+      name: https-admission-server
+      targetPort: 5443
+      appProtocol: https
+    - port: 5676
+      name: mads-server
+      appProtocol: https
+    - port: 5678
+      name: dp-server
+      appProtocol: https
+  selector:
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: kuma-control-plane
+  namespace: kuma-system
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+  annotations: 
+    
+spec:
+  replicas: 1
+  minReadySeconds: 0
+  strategy:
+    rollingUpdate:
+      maxSurge: 1
+      maxUnavailable: 0
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: kuma
+      app.kubernetes.io/instance: kuma
+      app: kuma-control-plane
+  template:
+    metadata:
+      annotations:
+        checksum/config: fd9d1d8386f97f2bd49e50f476520816168a1c9f60bbc43dec1347a64d239155
+        checksum/tls-secrets: d95caa5d7f340792bdf7442a6e6471e06db4f03129af1b84fb8baa4e9b82abcb
+      labels: 
+        app: kuma-control-plane
+        app.kubernetes.io/name: kuma
+        app.kubernetes.io/instance: kuma
+    spec:
+      affinity: 
+        podAntiAffinity:
+          preferredDuringSchedulingIgnoredDuringExecution:
+          - podAffinityTerm:
+              labelSelector:
+                matchExpressions:
+                - key: app.kubernetes.io/name
+                  operator: In
+                  values:
+                  - 'kuma'
+                - key: app.kubernetes.io/instance
+                  operator: In
+                  values:
+                  - 'kuma'
+                - key: app
+                  operator: In
+                  values:
+                  - 'kuma-control-plane'
+              topologyKey: kubernetes.io/hostname
+            weight: 100
+      securityContext:
+        runAsNonRoot: true
+      serviceAccountName: kuma-control-plane
+      automountServiceAccountToken: true
+      nodeSelector:
+        
+        kubernetes.io/os: linux
+      hostNetwork: false
+      terminationGracePeriodSeconds: 30
+      
+      containers:
+        - name: control-plane
+          image: "docker.io/kumahq/kuma-cp:0.0.1"
+          imagePullPolicy: IfNotPresent
+          securityContext:
+            readOnlyRootFilesystem: true
+          env:
+            - name: KUMA_API_SERVER_AUTHN_LOCALHOST_IS_ADMIN
+              value: "false"
+            - name: KUMA_API_SERVER_READ_ONLY
+              value: "true"
+            - name: KUMA_DEFAULTS_SKIP_MESH_CREATION
+              value: "false"
+            - name: KUMA_DP_SERVER_HDS_ENABLED
+              value: "false"
+            - name: KUMA_ENVIRONMENT
+              value: "kubernetes"
+            - name: KUMA_GENERAL_TLS_CERT_FILE
+              value: "/var/run/secrets/kuma.io/tls-cert/tls.crt"
+            - name: KUMA_GENERAL_TLS_KEY_FILE
+              value: "/var/run/secrets/kuma.io/tls-cert/tls.key"
+            - name: KUMA_INJECTOR_INIT_CONTAINER_IMAGE
+              value: "docker.io/kumahq/kuma-init:0.0.1"
+            - name: KUMA_MODE
+              value: "zone"
+            - name: KUMA_PLUGIN_POLICIES_ENABLED
+              value: "meshaccesslogs,meshcircuitbreakers,meshfaultinjections,meshhealthchecks,meshhttproutes,meshloadbalancingstrategies,meshmetrics,meshpassthroughs,meshproxypatches,meshratelimits,meshretries,meshtcproutes,meshtimeouts,meshtlses,meshtraces,meshtrafficpermissions"
+            - name: KUMA_RUNTIME_KUBERNETES_ADMISSION_SERVER_CERT_DIR
+              value: "/var/run/secrets/kuma.io/tls-cert"
+            - name: KUMA_RUNTIME_KUBERNETES_ADMISSION_SERVER_PORT
+              value: "5443"
+            - name: KUMA_RUNTIME_KUBERNETES_ALLOWED_USERS
+              value: "system:serviceaccount:kuma-system:kuma-control-plane"
+            - name: KUMA_RUNTIME_KUBERNETES_CONTROL_PLANE_SERVICE_NAME
+              value: "kuma-control-plane"
+            - name: KUMA_RUNTIME_KUBERNETES_INJECTOR_CA_CERT_FILE
+              value: "/var/run/secrets/kuma.io/tls-cert/ca.crt"
+            - name: KUMA_RUNTIME_KUBERNETES_INJECTOR_CNI_ENABLED
+              value: "false"
+            - name: KUMA_RUNTIME_KUBERNETES_INJECTOR_SIDECAR_CONTAINER_IMAGE
+              value: "docker.io/kumahq/kuma-dp:0.0.1"
+            - name: KUMA_STORE_KUBERNETES_SYSTEM_NAMESPACE
+              value: "kuma-system"
+            - name: KUMA_STORE_TYPE
+              value: "kubernetes"
+            - name: KUMA_INTER_CP_CATALOG_INSTANCE_ADDRESS
+              valueFrom:
+                fieldRef:
+                  fieldPath: status.podIP
+            - name: GOMEMLIMIT
+              valueFrom:
+                resourceFieldRef:
+                  containerName: control-plane
+                  resource: limits.memory
+            - name: GOMAXPROCS
+              valueFrom:
+                resourceFieldRef:
+                  containerName: control-plane
+                  resource: limits.cpu
+          args:
+            - run
+            - --log-level=info
+            - --log-output-path=
+            - --config-file=/etc/kuma.io/kuma-control-plane/config.yaml
+          ports:
+            - containerPort: 5680
+              name: diagnostics
+              protocol: TCP
+            - containerPort: 5681
+            - containerPort: 5682
+            - containerPort: 5443
+            - containerPort: 5678
+          livenessProbe:
+            timeoutSeconds: 10
+            httpGet:
+              path: /healthy
+              port: 5680
+          readinessProbe:
+            timeoutSeconds: 10
+            httpGet:
+              path: /ready
+              port: 5680
+          resources:
+            limits:
+              memory: 256Mi
+            requests:
+              cpu: 500m
+              memory: 256Mi
+          
+          volumeMounts:
+            - name: general-tls-cert
+              mountPath: /var/run/secrets/kuma.io/tls-cert/tls.crt
+              subPath: tls.crt
+              readOnly: true
+            - name: general-tls-cert
+              mountPath: /var/run/secrets/kuma.io/tls-cert/tls.key
+              subPath: tls.key
+              readOnly: true
+            - name: general-tls-cert
+              mountPath: /var/run/secrets/kuma.io/tls-cert/ca.crt
+              subPath: ca.crt
+              readOnly: true
+            - name: kuma-control-plane-config
+              mountPath: /etc/kuma.io/kuma-control-plane
+              readOnly: true
+            - name: tmp
+              mountPath: /tmp
+      volumes:
+        - name: general-tls-cert
+          secret:
+            secretName: general-tls-secret
+        - name: kuma-control-plane-config
+          configMap:
+            name: kuma-control-plane-config
+        - name: tmp
+          emptyDir: {}
+---
+apiVersion: admissionregistration.k8s.io/v1
+kind: MutatingWebhookConfiguration
+metadata:
+  name: kuma-admission-mutating-webhook-configuration
+  namespace: kuma-system
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+webhooks:
+  - name: mesh.defaulter.kuma-admission.kuma.io
+    admissionReviewVersions: ["v1"]
+    failurePolicy: Fail
+    namespaceSelector:
+      matchExpressions:
+        - key: kuma.io/sidecar-injection
+          operator: Exists
+        - key: kubernetes.io/metadata.name
+          operator: NotIn
+          values: 
+          - kube-system
+    clientConfig:
+      caBundle: XYZ
+      service:
+        namespace: kuma-system
+        name: kuma-control-plane
+        path: /default-kuma-io-v1alpha1-mesh
+    rules:
+      - apiGroups:
+          - kuma.io
+        apiVersions:
+          - v1alpha1
+        operations:
+          - CREATE
+          - UPDATE
+        resources:
+          - meshes
+          - dataplanes
+          - dataplaneinsights
+          - meshgateways
+          - zoneingresses
+          - zoneingressinsights
+          - zoneegresses
+          - zoneegressinsights
+          - serviceinsights
+          - zone
+          - zoneinsights
+          - meshaccesslogs
+          - meshcircuitbreakers
+          - meshfaultinjections
+          - meshhealthchecks
+          - meshhttproutes
+          - meshloadbalancingstrategies
+          - meshmetrics
+          - meshpassthroughs
+          - meshproxypatches
+          - meshratelimits
+          - meshretries
+          - meshtcproutes
+          - meshtimeouts
+          - meshtlses
+          - meshtraces
+          - meshtrafficpermissions
+          - hostnamegenerators
+          - meshexternalservices
+          - meshmultizoneservices
+          - meshservices
+    sideEffects: None
+  - name: owner-reference.kuma-admission.kuma.io
+    admissionReviewVersions: ["v1"]
+    failurePolicy: Fail
+    namespaceSelector:
+      matchExpressions:
+        - key: kuma.io/sidecar-injection
+          operator: Exists
+        - key: kubernetes.io/metadata.name
+          operator: NotIn
+          values: 
+          - kube-system
+    clientConfig:
+      caBundle: XYZ
+      service:
+        namespace: kuma-system
+        name: kuma-control-plane
+        path: /owner-reference-kuma-io-v1alpha1
+    rules:
+      - apiGroups:
+          - kuma.io
+        apiVersions:
+          - v1alpha1
+        operations:
+          - CREATE
+        resources:
+          - circuitbreakers
+          - externalservices
+          - faultinjections
+          - healthchecks
+          - meshgateways
+          - meshgatewayroutes
+          - proxytemplates
+          - ratelimits
+          - retries
+          - timeouts
+          - trafficlogs
+          - trafficpermissions
+          - trafficroutes
+          - traffictraces
+          - virtualoutbounds
+          - meshaccesslogs
+          - meshcircuitbreakers
+          - meshfaultinjections
+          - meshhealthchecks
+          - meshhttproutes
+          - meshloadbalancingstrategies
+          - meshmetrics
+          - meshpassthroughs
+          - meshproxypatches
+          - meshratelimits
+          - meshretries
+          - meshtcproutes
+          - meshtimeouts
+          - meshtlses
+          - meshtraces
+          - meshtrafficpermissions
+          - hostnamegenerators
+          - meshexternalservices
+          - meshmultizoneservices
+          - meshservices
+  
+      
+    sideEffects: None
+  - name: namespace-kuma-injector.kuma.io
+    admissionReviewVersions: ["v1"]
+    failurePolicy: Fail
+    namespaceSelector:
+      matchExpressions:
+        - key: kubernetes.io/metadata.name
+          operator: NotIn
+          values: 
+          - kube-system
+        - key: kuma.io/sidecar-injection
+          operator: In
+          values: 
+          - enabled
+          - "true"
+    clientConfig:
+      caBundle: XYZ
+      service:
+        namespace: kuma-system
+        name: kuma-control-plane
+        path: /inject-sidecar
+    rules:
+      - apiGroups:
+          - ""
+        apiVersions:
+          - v1
+        operations:
+          - CREATE
+        resources:
+          - pods
+    sideEffects: None
+  - name: pods-kuma-injector.kuma.io
+    admissionReviewVersions: ["v1"]
+    failurePolicy: Fail
+    namespaceSelector:
+      matchExpressions:
+        - key: kuma.io/sidecar-injection
+          operator: Exists
+        - key: kubernetes.io/metadata.name
+          operator: NotIn
+          values:
+          - kube-system
+          - kuma-system
+    objectSelector:
+      matchLabels:
+        kuma.io/sidecar-injection: enabled
+    clientConfig:
+      caBundle: XYZ
+      service:
+        namespace: kuma-system
+        name: kuma-control-plane
+        path: /inject-sidecar
+    rules:
+      - apiGroups:
+          - ""
+        apiVersions:
+          - v1
+        operations:
+          - CREATE
+        resources:
+          - pods
+    sideEffects: None
+---
+apiVersion: admissionregistration.k8s.io/v1
+kind: ValidatingWebhookConfiguration
+metadata:
+  name: kuma-validating-webhook-configuration
+  namespace: kuma-system
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+webhooks:
+  - name: validator.kuma-admission.kuma.io
+    admissionReviewVersions: ["v1"]
+    failurePolicy: Fail
+    namespaceSelector:
+      matchExpressions:
+        - key: kuma.io/sidecar-injection
+          operator: Exists
+        - key: kubernetes.io/metadata.name
+          operator: NotIn
+          values: 
+          - kube-system
+    clientConfig:
+      caBundle: XYZ
+      service:
+        namespace: kuma-system
+        name: kuma-control-plane
+        path: /validate-kuma-io-v1alpha1
+    rules:
+      - apiGroups:
+          - kuma.io
+        apiVersions:
+          - v1alpha1
+        operations:
+          - CREATE
+          - UPDATE
+          - DELETE
+        resources:
+          - circuitbreakers
+          - dataplanes
+          - externalservices
+          - faultinjections
+          - meshgatewayinstances
+          - healthchecks
+          - meshes
+          - meshgateways
+          - meshgatewayroutes
+          - proxytemplates
+          - ratelimits
+          - retries
+          - trafficlogs
+          - trafficpermissions
+          - trafficroutes
+          - traffictraces
+          - virtualoutbounds
+          - zones
+          - containerpatches
+          - meshaccesslogs
+          - meshcircuitbreakers
+          - meshfaultinjections
+          - meshhealthchecks
+          - meshhttproutes
+          - meshloadbalancingstrategies
+          - meshmetrics
+          - meshpassthroughs
+          - meshproxypatches
+          - meshratelimits
+          - meshretries
+          - meshtcproutes
+          - meshtimeouts
+          - meshtlses
+          - meshtraces
+          - meshtrafficpermissions
+          - hostnamegenerators
+          - meshexternalservices
+          - meshmultizoneservices
+          - meshservices
+    
+      
+    sideEffects: None
+  - name: secret.validator.kuma-admission.kuma.io
+    admissionReviewVersions: ["v1"]
+    namespaceSelector:
+      matchExpressions:
+        - key: kubernetes.io/metadata.name
+          operator: In
+          values:
+          - kuma-system
+    failurePolicy: Ignore
+    clientConfig:
+      caBundle: XYZ
+      service:
+        namespace: kuma-system
+        name: kuma-control-plane
+        path: /validate-v1-secret
+    rules:
+      - apiGroups:
+          - ""
+        apiVersions:
+          - v1
+        operations:
+          - CREATE
+          - UPDATE
+          - DELETE
+        resources:
+          - secrets
+    sideEffects: None
diff --git a/app/kumactl/cmd/install/testdata/install-cp-helm/roleBindingInNamespaces.values.yaml b/app/kumactl/cmd/install/testdata/install-cp-helm/roleBindingInNamespaces.values.yaml
new file mode 100644
index 000000000..6f70adf86
--- /dev/null
+++ b/app/kumactl/cmd/install/testdata/install-cp-helm/roleBindingInNamespaces.values.yaml
@@ -0,0 +1,1 @@
+enabledNamespaces: ["kuma-demo", "kuma-test"]
diff --git a/app/kumactl/cmd/install/testdata/install-cp-helm/securityContext.golden.yaml b/app/kumactl/cmd/install/testdata/install-cp-helm/securityContext.golden.yaml
index c6b6b9c6b..4a13bc5ba 100644
--- a/app/kumactl/cmd/install/testdata/install-cp-helm/securityContext.golden.yaml
+++ b/app/kumactl/cmd/install/testdata/install-cp-helm/securityContext.golden.yaml
@@ -41,36 +41,34 @@ metadata:
     app.kubernetes.io/name: kuma
     app.kubernetes.io/instance: kuma
 rules:
+  # Kubernetes resources
   - apiGroups:
       - ""
     resources:
       - namespaces
       - pods
       - nodes
+      - services
     verbs:
       - get
       - list
       - watch
   - apiGroups:
-    - "discovery.k8s.io"
+      - "discovery.k8s.io"
     resources:
       - endpointslices
     verbs:
-    - get
-    - list
-    - watch
+      - get
+      - list
+      - watch
   - apiGroups:
       - "apps"
     resources:
       - deployments
       - replicasets
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - "batch"
@@ -80,70 +78,36 @@ rules:
       - get
       - list
       - watch
-  - apiGroups:
+  - apiGroups: # Gateway API
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses
       - gateways
       - referencegrants
       - httproutes
     verbs:
-      - create
-      - delete
       - get
       - list
-      - patch
-      - update
       - watch
   - apiGroups:
       - gateway.networking.k8s.io
     resources:
-      - gatewayclasses/status
-      - gateways/status
-      - httproutes/status
+      - gatewayclasses # ClusterScope
     verbs:
+      - create
+      - delete
       - get
+      - list
       - patch
       - update
-  - apiGroups:
-      - coordination.k8s.io
-    resources:
-      - leases
-    verbs:
-      - get
-      - list
       - watch
-      - create
-      - update
-      - patch
-      - delete
-  - apiGroups:
-      - ""
-    resources:
-      - events
-    verbs:
-      - create
-      - patch
   - apiGroups:
-      - ""
+      - gateway.networking.k8s.io
     resources:
-      - services
+      - gatewayclasses/status # ClusterScope
     verbs:
       - get
-      - delete
-      - list
-      - watch
-      - create
-      - update
       - patch
-  - apiGroups:
-    - "discovery.k8s.io"
-    resources:
-    - endpointslices
-    verbs:
-    - get
-    - list
-    - watch
+      - update
   - apiGroups:
       - kuma.io
     resources:
@@ -215,6 +179,65 @@ rules:
       - get
       - patch
       - update
+  # validate k8s token before issuing mTLS cert
+  - apiGroups:
+      - authentication.k8s.io
+    resources:
+      - tokenreviews
+    verbs:
+      - create
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+rules:
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
+  - apiGroups:
+    # required by MeshGateway
+      - "apps"
+    resources:
+      - deployments
+      - replicasets
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - "batch"
+    resources:
+      - jobs
+    verbs:
+      - get
+      - list
+      - watch
+  - apiGroups:
+    # required by MeshGateway
+      - ""
+    resources:
+      - services
+    verbs:
+      - get
+      - delete
+      - list
+      - watch
+      - create
+      - update
+      - patch
   - apiGroups:
       - ""
     resources:
@@ -223,13 +246,30 @@ rules:
       - get
       - patch
       - update
-  # validate k8s token before issuing mTLS cert
   - apiGroups:
-      - authentication.k8s.io
+    # Gateway API
+      - gateway.networking.k8s.io
     resources:
-      - tokenreviews
+      - gateways
+      - referencegrants
+      - httproutes
     verbs:
       - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
@@ -249,6 +289,23 @@ subjects:
     namespace: kuma-system
 ---
 apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: kuma-control-plane-writer
+  labels: 
+    app: kuma-control-plane
+    app.kubernetes.io/name: kuma
+    app.kubernetes.io/instance: kuma
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: kuma-control-plane-writer
+subjects:
+  - kind: ServiceAccount
+    name: kuma-control-plane
+    namespace: kuma-system
+---
+apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
   name: kuma-control-plane
@@ -259,9 +316,9 @@ metadata:
     app.kubernetes.io/instance: kuma
 rules:
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - secrets
+      - leases
     verbs:
       - get
       - list
@@ -274,14 +331,22 @@ rules:
       - ""
     resources:
       - configmaps
+      - secrets
     verbs:
       - get
+      - delete
       - list
       - watch
       - create
       - update
       - patch
-      - delete
+  - apiGroups:
+      - ""
+    resources:
+      - events
+    verbs:
+      - create
+      - patch
   # leader-for-life election deletes Pods in some circumstances
   - apiGroups:
       - ""
@@ -289,6 +354,29 @@ rules:
       - pods
     verbs:
       - delete
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways
+      - referencegrants
+      - httproutes
+    verbs:
+      - create
+      - delete
+      - get
+      - list
+      - patch
+      - update
+      - watch
+  - apiGroups:
+      - gateway.networking.k8s.io
+    resources:
+      - gateways/status
+      - httproutes/status
+    verbs:
+      - get
+      - patch
+      - update
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding