Skip to content

feat(helm): gate cluster-scoped RBAC so the gateway chart can be installed without cluster-admin #3043

Description

@i-aka-rahul

User Story

As a platform operator installing OpenShell on a shared or restricted Kubernetes cluster, I want cluster-scoped chart objects (ClusterRole and ClusterRoleBinding) to be optional, so a cluster-admin can apply those objects once and a namespace-admin can install or upgrade the OpenShell gateway chart without cluster-admin privileges.

Problem Statement

The published OpenShell Helm chart always renders cluster-scoped RBAC as part of the same release as the gateway workload.

Today deploy/helm/openshell/templates/clusterrole.yaml and clusterrolebinding.yaml have no values guard. A helm install / helm upgrade of the chart therefore always attempts to create:

ClusterRole -node-reader (TokenReview, nodes, namespaces, and additional cluster-wide rules in managed/operator workspace modes)
ClusterRoleBinding -node-reader (binds that ClusterRole to the gateway ServiceAccount)
Other chart objects already have create/enable flags (serviceAccount.create, sandboxServiceAccount.create, grpcRoute.gateway.create, credential-driver rbac.create). Cluster-scoped RBAC does not. There is no supported way to install only the namespaced gateway objects while leaving ClusterRole / ClusterRoleBinding to a separate cluster-admin step.

This is a different split from #2485 (gateway vs workspace-namespace charts). Even a gateway-only install would still include cluster-scoped RBAC.

Impact / Why This Matters

Without this feature, users must run the OpenShell Helm release as cluster-admin, even when they only need to deploy namespaced objects (Deployment/StatefulSet, Service, ServiceAccount, ConfigMaps, Secrets, and namespaced Role/RoleBinding).

That is insufficient for many customer environments:

The installer is a namespace-admin GitOps or platform controller that cannot create ClusterRole or ClusterRoleBinding.
Cluster-scoped RBAC is owned by a cluster-admin / HOM team and must not be applied by application Helm releases.
Mixing cluster-scoped and namespaced objects in one release forces a privilege escalation of the entire OpenShell install, or it fails with forbidden: User cannot create resource "clusterroles" in API group "rbac.authorization.k8s.io" at the cluster scope.
Workarounds today are all fragile: fork and patch the chart, post-process helm template output, or disable serviceAccount.create and hand-roll RBAC while still fighting the unconditional ClusterRole templates. That blocks clean adoption on enterprise and OpenShift clusters that separate cluster-admin from namespace-admin.

This matters because it is a packaging/privilege boundary, not a missing runtime capability. The gateway already works if ClusterRole/ClusterRoleBinding exist; the chart just will not let a non-admin user install it.

Proposed Design

From the operator’s point of view, installing OpenShell on a restricted cluster should be two Helm (or equivalent) steps with a clear ownership boundary:

Cluster-admin (once per cluster, or once per gateway ServiceAccount)
Apply the cluster-scoped objects the gateway needs (ClusterRole and ClusterRoleBinding whose subject is the gateway ServiceAccount in the release namespace). These may live in a separate admin chart, a documented manifest, or the same OpenShell chart with cluster objects enabled.

Namespace-admin (normal OpenShell install/upgrade)
Install the OpenShell chart with cluster-scoped objects omitted. The release creates only namespaced resources. The gateway ServiceAccount name and namespace remain stable so the pre-created ClusterRoleBinding still matches.

Observable behavior:

Default install stays as it is today: cluster-scoped RBAC is created, so existing cluster-admin installs do not change.
When the omit/disable value is set, helm template / helm install does not emit ClusterRole or ClusterRoleBinding.
Chart docs list which objects are cluster-scoped vs namespaced, and show the two-step admin / non-admin workflow (including that ClusterRoleBinding subjects must match the gateway ServiceAccount created by the namespaced release).
The flag is independent of workspace mode (shared / managed / operator). Those modes may change what the ClusterRole contains; they should not force a namespace-admin to apply it.
Exact value names and whether this is one flag or a small RBAC create block can follow existing chart conventions (serviceAccount.create, credential-driver rbac.create). The user-facing contract is: cluster-scoped objects are skippable without forking the chart.

Acceptance Criteria

  • Default chart render still includes ClusterRole and ClusterRoleBinding (no behavior change for current installs).
  • A documented chart value omits ClusterRole and ClusterRoleBinding from the render (helm template shows neither kind: ClusterRole nor kind: ClusterRoleBinding).
  • With that value set, the remaining objects are namespaced and a namespace-admin can helm install / helm upgrade the chart without cluster-scoped RBAC permissions.
  • ClusterRoleBinding, when created (default path or a separate admin install), still binds to the gateway ServiceAccount name and namespace used by the namespaced release.
  • Helm README / Kubernetes setup docs describe the cluster-admin vs namespace-admin split and list the cluster-scoped objects.
  • Existing serviceAccount.create=false + custom ServiceAccount workflow still works when cluster RBAC is created separately.

Alternatives Considered

  • Always require cluster-admin for the OpenShell release. Simplest for the chart, but it blocks customers whose platform installer is namespace-admin only, and it mixes privilege levels that security teams keep separate.
  • Disable serviceAccount.create and supply a pre-created ServiceAccount. Docs already mention this for custom RBAC, but the ClusterRole templates still render, so Helm still tries to create cluster-scoped objects. That does not solve the problem.
  • Split into two published charts (gateway vs workspace) as in #2485. Useful for tenant-namespace ownership, but the gateway chart is still expected to carry cluster-scoped runtime permissions. A workspace split does not give a namespace-admin gateway install.
  • Post-process helm template or maintain a forked chart. Works as a local workaround; it is not a supported, versioned interface and drifts on every upstream chart change.

A create/omit flag on cluster-scoped objects is the smallest user-facing change that preserves today’s default and unblocks the two-user (admin / non-admin) install path.

Agent Investigation

  • Reviewed deploy/helm/openshell/templates/clusterrole.yaml and clusterrolebinding.yaml: neither is gated on a values flag.
  • Reviewed values.yaml: serviceAccount.create, sandboxServiceAccount.create, grpcRoute.gateway.create, and server.credentialDrivers.kubernetesSecrets.rbac.create already exist; there is no equivalent for ClusterRole / ClusterRoleBinding.
  • Kubernetes setup docs state the chart creates ClusterRole + ClusterRoleBinding openshell-node-reader as part of a normal install (docs).
  • Related but not a duplicate:
    • #2485 — split gateway vs workspace-namespace charts; gateway chart still owns cluster-scoped RBAC.
    • #1018 — document RBAC requirements; does not add a skip flag.

Checklist

  • I've reviewed existing issues and the architecture docs
  • This is a design proposal, not a "please build this" request

Metadata

Metadata

Assignees

No one assigned

    Labels

    state:triage-neededOpened without agent diagnostics and needs triage

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions