Skip to content

Commit eaaefde

Browse files
MatteoMori8claude
andauthored
feat(helm): configurable RBAC with read-only ClusterRole support (#46)
Signed-off-by: Matteo Mori <matteo.mori@rvu.co.uk> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e4347f5 commit eaaefde

File tree

3 files changed

+111
-50
lines changed

3 files changed

+111
-50
lines changed
Lines changed: 82 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,95 @@
1-
{{- if not .Values.useDefaultServiceAccount }}
1+
{{- if and (not .Values.useDefaultServiceAccount) .Values.rbac.create }}
2+
{{- if .Values.rbac.readOnly }}
23
apiVersion: rbac.authorization.k8s.io/v1
34
kind: ClusterRole
45
metadata:
5-
name: {{ include "kagent.fullname" . }}-cluster-admin-role
6+
name: {{ include "kagent.fullname" . }}-read-role
67
labels:
78
{{- include "kagent.labels" . | nindent 4 }}
89
rules:
9-
- apiGroups: ["*"]
10-
resources: ["*"]
11-
verbs: ["*"]
12-
- nonResourceURLs: ["*"]
13-
verbs: ["*"]
14-
---
10+
# Core workload resources
11+
- apiGroups: [""]
12+
resources:
13+
- pods
14+
- services
15+
- endpoints
16+
- configmaps
17+
- serviceaccounts
18+
- persistentvolumeclaims
19+
- replicationcontrollers
20+
- namespaces
21+
verbs: ["get", "list", "watch"]
22+
23+
# Pod logs (subresource)
24+
- apiGroups: [""]
25+
resources:
26+
- pods/log
27+
verbs: ["get", "list"]
28+
29+
# Events
30+
- apiGroups: [""]
31+
resources:
32+
- events
33+
verbs: ["get", "list", "watch"]
34+
- apiGroups: ["events.k8s.io"]
35+
resources:
36+
- events
37+
verbs: ["get", "list", "watch"]
38+
39+
# Apps workloads
40+
- apiGroups: ["apps"]
41+
resources:
42+
- deployments
43+
- statefulsets
44+
- daemonsets
45+
- replicasets
46+
verbs: ["get", "list", "watch"]
47+
48+
# Batch workloads
49+
- apiGroups: ["batch"]
50+
resources:
51+
- jobs
52+
- cronjobs
53+
verbs: ["get", "list", "watch"]
1554

55+
# Networking
56+
- apiGroups: ["networking.k8s.io"]
57+
resources:
58+
- ingresses
59+
- networkpolicies
60+
verbs: ["get", "list", "watch"]
61+
62+
# Autoscaling
63+
- apiGroups: ["autoscaling"]
64+
resources:
65+
- horizontalpodautoscalers
66+
verbs: ["get", "list", "watch"]
67+
68+
{{- if .Values.rbac.allowSecrets }}
69+
# Secrets (opt-in)
70+
- apiGroups: [""]
71+
resources:
72+
- secrets
73+
verbs: ["get", "list", "watch"]
74+
{{- end }}
75+
76+
{{- with .Values.rbac.additionalRules }}
77+
# Additional user-defined rules
78+
{{- toYaml . | nindent 2 }}
79+
{{- end }}
80+
81+
{{- else }}
1682
apiVersion: rbac.authorization.k8s.io/v1
1783
kind: ClusterRole
1884
metadata:
19-
name: {{ include "kagent.fullname" . }}-read-role
85+
name: {{ include "kagent.fullname" . }}-cluster-admin-role
2086
labels:
2187
{{- include "kagent.labels" . | nindent 4 }}
2288
rules:
23-
- apiGroups: ["*"]
24-
resources: ["*"]
25-
verbs: ["*"]
26-
- nonResourceURLs: ["*"]
27-
verbs:
28-
- get
29-
- list
30-
- watch
31-
{{- end }}
89+
- apiGroups: ["*"]
90+
resources: ["*"]
91+
verbs: ["*"]
92+
- nonResourceURLs: ["*"]
93+
verbs: ["*"]
94+
{{- end }}
95+
{{- end }}
Lines changed: 10 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,24 @@
1-
{{- if not .Values.useDefaultServiceAccount }}
1+
{{- if and (not .Values.useDefaultServiceAccount) .Values.rbac.create }}
22
apiVersion: rbac.authorization.k8s.io/v1
33
kind: ClusterRoleBinding
44
metadata:
5+
{{- if .Values.rbac.readOnly }}
6+
name: {{ include "kagent.fullname" . }}-read-rolebinding
7+
{{- else }}
58
name: {{ include "kagent.fullname" . }}-cluster-admin-rolebinding
9+
{{- end }}
610
labels:
711
{{- include "kagent.labels" . | nindent 4 }}
812
roleRef:
913
apiGroup: rbac.authorization.k8s.io
1014
kind: ClusterRole
15+
{{- if .Values.rbac.readOnly }}
16+
name: {{ include "kagent.fullname" . }}-read-role
17+
{{- else }}
1118
name: {{ include "kagent.fullname" . }}-cluster-admin-role
19+
{{- end }}
1220
subjects:
1321
- kind: ServiceAccount
1422
name: {{ include "kagent.fullname" . }}
1523
namespace: {{ include "kagent.namespace" . }}
16-
---
17-
apiVersion: rbac.authorization.k8s.io/v1
18-
kind: ClusterRoleBinding
19-
metadata:
20-
name: {{ include "kagent.fullname" . }}-getter-rolebinding
21-
labels:
22-
{{- include "kagent.labels" . | nindent 4 }}
23-
roleRef:
24-
apiGroup: rbac.authorization.k8s.io
25-
kind: ClusterRole
26-
name: {{ include "kagent.fullname" . }}-getter-role
27-
subjects:
28-
- kind: ServiceAccount
29-
name: {{ include "kagent.fullname" . }}
30-
namespace: {{ include "kagent.namespace" . }}
31-
---
32-
apiVersion: rbac.authorization.k8s.io/v1
33-
kind: ClusterRoleBinding
34-
metadata:
35-
name: {{ include "kagent.fullname" . }}-writer-rolebinding
36-
labels:
37-
{{- include "kagent.labels" . | nindent 4 }}
38-
roleRef:
39-
apiGroup: rbac.authorization.k8s.io
40-
kind: ClusterRole
41-
name: {{ include "kagent.fullname" . }}-writer-role
42-
subjects:
43-
- kind: ServiceAccount
44-
name: {{ include "kagent.fullname" . }}
45-
namespace: {{ include "kagent.namespace" . }}
46-
{{- end }}
24+
{{- end }}

helm/kagent-tools/values.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,25 @@ topologySpreadConstraints: []
9191
# topologyKey: topology.kubernetes.io/zone
9292
# whenUnsatisfiable: DoNotSchedule
9393

94+
rbac:
95+
# When false, no ClusterRole or ClusterRoleBinding are created.
96+
# The ServiceAccount is still created allowing you to attach your own roles externally.
97+
create: true
98+
# When true, deploys a read-only ClusterRole (get, list, watch) instead of cluster-admin.
99+
# Pairs well with the --read-only CLI flag which disables write operations at the application layer.
100+
# Only applies when rbac.create is true.
101+
# Defaults to False as to not introduce breaking changes. Worth revisiting later on.
102+
readOnly: false
103+
# When readOnly is true, grants read access to Secrets. Default: no access to Secrets.
104+
# Ignored when readOnly is false (admin already has full access).
105+
allowSecrets: false
106+
# Extra rules appended to the read-only ClusterRole. Useful for granting read access to CRDs (Istio, Cilium, Argo, etc.).
107+
# Ignored when readOnly is false (admin already has full access).
108+
additionalRules: []
109+
# - apiGroups: ["networking.istio.io"]
110+
# resources: ["virtualservices", "destinationrules", "gateways"]
111+
# verbs: ["get", "list", "watch"]
112+
94113
otel:
95114
tracing:
96115
enabled: false

0 commit comments

Comments
 (0)