Conversation
ansjindal
requested review from
a team,
derekwaynecarr,
mrunalp and
sjenning
as code owners
September 18, 2026 12:19
|
All contributors have signed the DCO ✍️ ✅ |
The gateway chart always rendered the ClusterRole and ClusterRoleBinding, so
every install and upgrade required cluster-admin even when only namespaced
objects were needed. Installers that are namespace-admin GitOps or platform
controllers could not run the release at all, and clusters where cluster-scoped
RBAC is owned by a separate team had no supported way to split the install.
Add an rbac values block so a cluster-admin can apply the cluster-scoped objects
once and a namespace-admin can install and upgrade the release without
cluster-scoped permissions:
rbac:
create: true
clusterScoped:
create: true
clusterRoleName: ""
clusterRoleBindingName: ""
rbac.clusterScoped.create gates the ClusterRole and ClusterRoleBinding, and is
independent of the workspace mode. rbac.create additionally gates the namespaced
sandbox Role and RoleBinding, which matters because Kubernetes escalation
prevention stops an installer holding only the built-in admin role from creating
a Role that grants agents.x-k8s.io verbs it does not itself hold. The certgen
hook and credential driver RBAC keep their existing flags.
Both flags default to true, so current installs are unchanged. The helpers treat
a missing rbac block as enabled so upgrades with --reuse-values do not drop RBAC,
matching the existing workspaceResources pattern. The ClusterRoleBinding roleRef
follows clusterRoleName so a separately applied ClusterRole can carry a name the
cluster-admin chooses.
Document the migration for a release that already owns the cluster-scoped
objects: Helm deletes objects that leave the manifest, so annotate them with
helm.sh/resource-policy=keep before setting the flag, otherwise the gateway
loses TokenReview until a cluster-admin re-applies them.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: ansjindal <ansjindal@nvidia.com>
ansjindal
force-pushed
the
feat/optional-cluster-scoped-rbac
branch
from
September 18, 2026 12:23
c5c9173 to
e876b74
Compare
Author
|
I have read the DCO document and I hereby sign the DCO. |
Author
|
recheck |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Makes the gateway chart's cluster-scoped RBAC optional so a cluster-admin can apply the
ClusterRoleandClusterRoleBindingonce and a namespace-admin can install and upgrade the OpenShell release without cluster-scoped permissions. Both new flags default totrue, so existing installs are unchanged.Related Issue
Fixes #3043
Changes
rbacvalues block following the shape proposed on the issue:rbac.create,rbac.clusterScoped.create,rbac.clusterScoped.clusterRoleName,rbac.clusterScoped.clusterRoleBindingName.clusterrole.yamlandclusterrolebinding.yamlonrbac.clusterScoped.create, independent ofserver.drivers.kubernetes.workspaceMode.role.yaml/rolebinding.yamlonrbac.create. This is not merely a parent switch: insharedmode, Kubernetes escalation prevention stops an installer holding only the built-inadminrole from creating a Role that grantsagents.x-k8s.ioverbs it does not itself hold, so such an installer needsrbac.create=falsewith all RBAC applied out of band. The certgen hook and credential driver RBAC keep their existing flags.rbacblock as enabled, sohelm upgrade --reuse-valuesfrom a pre-change release does not drop RBAC — the same pattern asopenshell.workspaceResourcesEnabled.ClusterRoleBindingroleReffromclusterRoleNameso a separately applied ClusterRole can carry a cluster-admin-chosen name.ci/values-namespace-admin.yaml, picked up automatically by thehelm:lintoverlay loop.docs/kubernetes/setup.mdx. This also corrects the documented ClusterRole name, which isopenshell-node-reader-<namespace>.deploy/helm/test-split-ownership.shto assert arbac.clusterScoped.create=falserender emits no cluster-scoped objects while keeping the gateway ServiceAccount.Migration note for reviewers: Helm deletes objects that leave a release manifest, so setting the flag on a release that already owns the cluster-scoped objects deletes them, and the gateway loses TokenReview until a cluster-admin re-applies them. The docs prescribe annotating them with
helm.sh/resource-policy=keepfirst; this was tested and hands ownership over with no gap.Testing
mise run pre-commitpassesmise run pre-commit(fmt + lint) exits 0 andfmtproduces no diff. Thelinthalf covers all 15 subtasks, includinghelm:lintacross all 19 CI overlays,helm:docs:check,helm:test,license:checkover 1045 files, clippy, and markdown/mermaid.Unit tests — 14 new cases across
clusterrole_test.yaml(5),clusterrolebinding_test.yaml(5), and a newrbac_test.yaml(4): default still renders both objects; each flag omits the right objects; omission is independent of workspace mode; name overrides land inmetadata.nameandroleRef;serviceAccount.create=falsestill yields a correct binding subject; and legacy values with norbackey still create RBAC. Gateway suite is 163 tests / 15 suites, workspace 4 / 1, plustest-split-ownership.sh, whose new assertion was negative-controlled by flipping the flag to confirm it fails.Live cluster (k3d, agent-sandbox v1.0.2,
--kube-as-userimpersonation of an identity holding only the built-inadminrole in one namespace, asserted unable to get or create ClusterRoles/ClusterRoleBindings):clusterroles ... is forbidden ... at the cluster scope.rbac.clusterScoped.create=false— cluster-admin applies the two cluster-scoped objects; namespace-admin installs and upgrades; StatefulSet rolls out; release still owns the namespaced Role/RoleBinding; the pre-created binding matches the release's ServiceAccount, which can create TokenReviews.rbac.create=false— installer needs no RBAC write permission;helm get manifestconfirms the release claims no RBAC; admin-owned objects survive install and upgrade.serviceAccount.create=false+serviceAccount.name=my-existing-sawith RBAC applied separately: ClusterRoleBinding subject, RoleBinding subject, and podserviceAccountNameall resolve correctly; pod Running 1/1.forbidden, and it lists sandboxes through the namespaced Role.Workspace modes — 23 assertions, all pass.
managedandoperatorboth install and upgrade as a namespace-admin withrbac.clusterScoped.create=false, roll out, and log no permission errors. Mode-specific ClusterRole grants were verified to land:managedgets namespace create/delete, cluster-wide sandboxes, and serviceaccount create;operatorgets cluster-wide sandboxes but not namespace create; livekubectl auth can-ion the gateway SA matches per mode. Inmanaged/operatorthe chart renders no namespaced sandbox Role, so anadmin-only installer suffices; onlysharedneeds one of the two documented remedies, both verified.Backward compatibility — 15 assertions, each starting from a release installed with the pre-change chart from
mainand upgraded with this branch: default upgrade,--reuse-values, a pre-change values file,--set-json rbac=null,helm rollbackto the pre-change revision, and uninstall leaving no cluster-scoped residue. All pass; the cluster-scoped objects survive and stay release-owned in every case.Cluster-scope audit — all 19 CI overlays plus defaults were scanned against 16 cluster-scoped kinds (SCC, ClusterIssuer, GatewayClass, CRD, PV, StorageClass, webhooks, and others). Every overlay renders exactly
ClusterRole+ClusterRoleBindingand nothing else, and zero with the flag off, confirming the object inventory the docs now publish.Not covered: OpenShift SCC admission and Route behavior on a real OpenShift cluster. The three OpenShift overlays pass render-level checks and lint, but the live path needs an OpenShift cluster;
test:e2e-kubernetesmay be worth applying.Checklist
architecture/doc covers chart RBAC topology🤖 Generated with Claude Code