Skip to content

fix(helm): namespaceScope RBAC (avoid ClusterRole)#2595

Open
peterbueschel wants to merge 8 commits intografana:masterfrom
peterbueschel:fix/2594-namespace-scoped-rbac
Open

fix(helm): namespaceScope RBAC (avoid ClusterRole)#2595
peterbueschel wants to merge 8 commits intografana:masterfrom
peterbueschel:fix/2594-namespace-scoped-rbac

Conversation

@peterbueschel
Copy link
Copy Markdown

@peterbueschel peterbueschel commented Mar 20, 2026

Description

Fixes #2594

The chart currently always creates a ClusterRole even when namespaceScope=true. While binding a ClusterRole via a RoleBinding is namespace-scoped, creating the ClusterRole itself requires cluster-scoped RBAC and therefore breaks upgrades/installs in restricted clusters.

This PR introduces an explicit chart option:

  • rbac.useClusterRole=true (default): preserve existing behaviour (create ClusterRole and bind it either cluster-wide or via per-namespace RoleBindings when namespaceScope=true)
  • rbac.useClusterRole=false + namespaceScope=true: render namespaced Role + RoleBinding instead (no ClusterRole / ClusterRoleBinding)

Note: watchNamespaceSelector requires cluster-scoped permission to list namespaces and therefore requires rbac.useClusterRole=true.

Verification

Local render checks

cd deploy/helm/grafana-operator

# default behavior: namespaceScope=true still uses ClusterRole unless explicitly disabled
helm template test . --namespace testns \
  --set namespaceScope=true --set watchNamespaceSelector="" \
  | grep -E '^kind: ClusterRole$' >/dev/null && echo "OK" || echo "MISSING"

# restricted behavior: namespaceScope=true + rbac.useClusterRole=false must not render cluster-scoped RBAC
helm template test . --namespace testns \
  --set namespaceScope=true --set rbac.useClusterRole=false \
  --set watchNamespaces="" --set watchNamespaceSelector="" \
  | grep -E '^kind: (ClusterRole|ClusterRoleBinding)$' && echo "UNEXPECTED" || echo "OK"

# cluster-scope (default): should still render cluster-scoped RBAC
helm template test . --namespace testns --set namespaceScope=false \
  | grep -E '^kind: (ClusterRole|ClusterRoleBinding)$' >/dev/null && echo "OK" || echo "MISSING"

@cla-assistant
Copy link
Copy Markdown

cla-assistant bot commented Mar 20, 2026

CLA assistant check
All committers have signed the CLA.

@peterbueschel
Copy link
Copy Markdown
Author

Hi,
is there anything else to do in order to get this PR merged?

Copy link
Copy Markdown
Collaborator

@theSuess theSuess left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM from my side but would appreciate it if @Baarsgaard or @weisdd also take a glance as I never trust myself when it comes to helm templates 😅

@Baarsgaard
Copy link
Copy Markdown
Collaborator

I'll render and install the manifests later today and approve when I've tested it 😄

Copy link
Copy Markdown
Collaborator

@Baarsgaard Baarsgaard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had a small stumble while testing, otherwise this works great

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ include "grafana-operator.fullname" $ }}
Copy link
Copy Markdown
Collaborator

@Baarsgaard Baarsgaard Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried toggling rbac.useClusterRole on/off and it failed with:

Error: UPGRADE FAILED: cannot patch "grafana-operator" with kind RoleBinding: RoleBinding.rbac.authorization.k8s.io "grafana-operator" is invalid: roleRef: Invalid value: {"APIGroup":"rbac.authorization.k8s.io","Kind":"ClusterRole","Name":"grafana-operator"}: cannot change roleRef

Evidently, roleRef does not allow updates. Meaning I had to either uninstall the chart entirely or disable namespaceScope and re-enable it alongside rbac.useClusterRole.

One way to fix this is to create distinct RoleBindings depending on rbac.useClusterRole requiring Helm to delete the old one and create one with a different name.

Suggested change
name: {{ include "grafana-operator.fullname" $ }}
name: {{ include "grafana-operator.fullname" $ }}-{{ ternary "cluster-role" "role" $useClusterRole }}{{- /* Allows toggling rbac.useClusterRole without re-install or disabling namespaceScope */}}

If there's a better way, I'm open to suggestions but this is pretty simple and identical to the ternary deciding the roleRef.kind

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix this PR fixes a bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Helm chart >=5.22.0: namespaceScope=true still requires ClusterRole/ClusterRoleBinding

4 participants