From 80ffcc11e641d95bf07e6fc37618bfcf74545dc3 Mon Sep 17 00:00:00 2001 From: Lukas Piwowarski Date: Tue, 21 Jul 2026 15:36:28 +0200 Subject: [PATCH] Remove unnecessary RBAC verbs Applied principle of least privilege across all RBAC markers in openstacklightspeed_controller.go. Verbs were removed where code analysis confirmed they are never exercised by the controller or the controller-runtime framework. ClusterRole changes: - openstacklightspeeds: removed create, delete, update; get, list, watch, patch are sufficient for normal reconciliation - openstacklightspeeds/status: removed get, update; only patch is needed to update the status subresource - clusterroles: removed update, delete; CreateOrPatch uses get/create/patch, bulk removal uses deletecollection (DeleteAllOf) - clusterrolebindings: same reasoning as clusterroles - consoleplugins: removed update; get/list/watch/create/patch/delete cover all actual operations - clusterserviceversions: removed entirely; the controller does not interact with CSVs (the Owns() watch was also unused) Role (namespaced) changes: - networkpolicies: removed update; CreateOrPatch uses get/create/patch - deployments: removed update, delete; CreateOrPatch uses get/create/patch; owned resources are GC'd by Kubernetes - configmaps: removed update; get/list/watch/create/patch/delete cover all actual operations (one ConfigMap is explicitly deleted on toggle) - secrets: removed update; delete is retained because cleanupMCPResources individually deletes secrets; bulk removal uses deletecollection (DeleteAllOf) - services: removed update, delete; CreateOrPatch uses get/create/patch; owned resources are GC'd by Kubernetes - persistentvolumeclaims: removed update; get/list/watch/create/patch cover all actual operations; PVCs are intentionally never deleted Co-Authored-By: Claude Opus 4.6 --- ...tspeed-operator.clusterserviceversion.yaml | 45 ++----------------- config/rbac/role.yaml | 43 +----------------- .../openstacklightspeed_controller.go | 28 +++++------- 3 files changed, 17 insertions(+), 99 deletions(-) diff --git a/bundle/manifests/openstack-lightspeed-operator.clusterserviceversion.yaml b/bundle/manifests/openstack-lightspeed-operator.clusterserviceversion.yaml index edf6f8d..0b9dcc0 100644 --- a/bundle/manifests/openstack-lightspeed-operator.clusterserviceversion.yaml +++ b/bundle/manifests/openstack-lightspeed-operator.clusterserviceversion.yaml @@ -25,7 +25,7 @@ metadata: ] capabilities: Basic Install categories: AI/Machine Learning - createdAt: "2026-08-06T09:28:15Z" + createdAt: "2026-08-10T12:06:44Z" description: AI-powered virtual assistant for Red Hat OpenStack Services on OpenShift features.operators.openshift.io/cnf: "false" features.operators.openshift.io/cni: "false" @@ -227,7 +227,6 @@ spec: - get - list - patch - - update - watch - apiGroups: - core.openstack.org @@ -260,12 +259,9 @@ spec: resources: - openstacklightspeeds verbs: - - create - - delete - get - list - patch - - update - watch - apiGroups: - lightspeed.openstack.org @@ -278,9 +274,7 @@ spec: resources: - openstacklightspeeds/status verbs: - - get - patch - - update - apiGroups: - operator.openshift.io resources: @@ -290,14 +284,6 @@ spec: - list - update - watch - - apiGroups: - - operators.coreos.com - resources: - - clusterserviceversions - verbs: - - get - - list - - watch - apiGroups: - rbac.authorization.k8s.io resources: @@ -305,12 +291,10 @@ spec: - clusterroles verbs: - create - - delete - deletecollection - get - list - patch - - update - watch - apiGroups: - authentication.k8s.io @@ -447,25 +431,24 @@ spec: - "" resources: - configmaps - - services verbs: - create - delete - get - list - patch - - update - watch - apiGroups: - "" resources: - persistentvolumeclaims + - serviceaccounts + - services verbs: - create - get - list - patch - - update - watch - apiGroups: - "" @@ -478,17 +461,6 @@ spec: - get - list - patch - - update - - watch - - apiGroups: - - "" - resources: - - serviceaccounts - verbs: - - create - - get - - list - - patch - watch - apiGroups: - apps @@ -496,11 +468,9 @@ spec: - deployments verbs: - create - - delete - get - list - patch - - update - watch - apiGroups: - networking.k8s.io @@ -511,16 +481,7 @@ spec: - get - list - patch - - update - watch - - apiGroups: - - operators.coreos.com - resources: - - clusterserviceversions - verbs: - - delete - - patch - - update serviceAccountName: openstack-lightspeed-operator-controller-manager strategy: deployment installModes: diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index d47c08d..8d511d5 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -62,7 +62,6 @@ rules: - get - list - patch - - update - watch - apiGroups: - core.openstack.org @@ -95,12 +94,9 @@ rules: resources: - openstacklightspeeds verbs: - - create - - delete - get - list - patch - - update - watch - apiGroups: - lightspeed.openstack.org @@ -113,9 +109,7 @@ rules: resources: - openstacklightspeeds/status verbs: - - get - patch - - update - apiGroups: - operator.openshift.io resources: @@ -125,14 +119,6 @@ rules: - list - update - watch -- apiGroups: - - operators.coreos.com - resources: - - clusterserviceversions - verbs: - - get - - list - - watch - apiGroups: - rbac.authorization.k8s.io resources: @@ -140,12 +126,10 @@ rules: - clusterroles verbs: - create - - delete - deletecollection - get - list - patch - - update - watch --- apiVersion: rbac.authorization.k8s.io/v1 @@ -158,25 +142,24 @@ rules: - "" resources: - configmaps - - services verbs: - create - delete - get - list - patch - - update - watch - apiGroups: - "" resources: - persistentvolumeclaims + - serviceaccounts + - services verbs: - create - get - list - patch - - update - watch - apiGroups: - "" @@ -189,17 +172,6 @@ rules: - get - list - patch - - update - - watch -- apiGroups: - - "" - resources: - - serviceaccounts - verbs: - - create - - get - - list - - patch - watch - apiGroups: - apps @@ -207,11 +179,9 @@ rules: - deployments verbs: - create - - delete - get - list - patch - - update - watch - apiGroups: - networking.k8s.io @@ -222,13 +192,4 @@ rules: - get - list - patch - - update - watch -- apiGroups: - - operators.coreos.com - resources: - - clusterserviceversions - verbs: - - delete - - patch - - update diff --git a/internal/controller/openstacklightspeed_controller.go b/internal/controller/openstacklightspeed_controller.go index e362577..a42374f 100644 --- a/internal/controller/openstacklightspeed_controller.go +++ b/internal/controller/openstacklightspeed_controller.go @@ -25,7 +25,6 @@ import ( consolev1 "github.com/openshift/api/console/v1" "github.com/openstack-k8s-operators/lib-common/modules/common/condition" common_helper "github.com/openstack-k8s-operators/lib-common/modules/common/helper" - operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" @@ -75,13 +74,11 @@ func (r *OpenStackLightspeedReconciler) GetLogger(ctx context.Context) logr.Logg return log.FromContext(ctx).WithName("Controllers").WithName("OpenStackLightspeed") } -// +kubebuilder:rbac:groups=lightspeed.openstack.org,resources=openstacklightspeeds,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=lightspeed.openstack.org,resources=openstacklightspeeds/status,verbs=get;update;patch +// +kubebuilder:rbac:groups=lightspeed.openstack.org,resources=openstacklightspeeds,verbs=get;list;watch;patch +// +kubebuilder:rbac:groups=lightspeed.openstack.org,resources=openstacklightspeeds/status,verbs=patch // +kubebuilder:rbac:groups=lightspeed.openstack.org,resources=openstacklightspeeds/finalizers,verbs=update -// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterroles,verbs=get;list;watch;create;patch;update;delete;deletecollection -// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterrolebindings,verbs=get;list;watch;create;patch;update;delete;deletecollection -// +kubebuilder:rbac:groups=operators.coreos.com,resources=clusterserviceversions,verbs=get;list;watch -// +kubebuilder:rbac:groups=operators.coreos.com,resources=clusterserviceversions,namespace=openstack-lightspeed,verbs=update;patch;delete +// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterroles,verbs=get;list;watch;create;patch;deletecollection +// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterrolebindings,verbs=get;list;watch;create;patch;deletecollection // +kubebuilder:rbac:groups=config.openshift.io,resources=clusterversions,verbs=get;list;watch // SAR role escalation: the operator creates a ClusterRole granting pull-secret GET, // so it must hold that permission itself (K8s RBAC escalation prevention). @@ -97,15 +94,15 @@ func (r *OpenStackLightspeedReconciler) GetLogger(ctx context.Context) logr.Logg // +kubebuilder:rbac:groups=core.openstack.org,resources=openstackcontrolplanes,verbs=get;list;watch // +kubebuilder:rbac:groups=keystone.openstack.org,resources=keystoneapplicationcredentials,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=keystone.openstack.org,resources=keystoneapplicationcredentials/status,verbs=get -// +kubebuilder:rbac:groups=networking.k8s.io,resources=networkpolicies,namespace=openstack-lightspeed,verbs=get;list;watch;create;patch;update -// +kubebuilder:rbac:groups=apps,resources=deployments,namespace=openstack-lightspeed,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups="",resources=configmaps,namespace=openstack-lightspeed,verbs=get;list;watch;create;patch;update;delete -// +kubebuilder:rbac:groups="",resources=secrets,namespace=openstack-lightspeed,verbs=get;list;watch;create;patch;update;delete;deletecollection -// +kubebuilder:rbac:groups="",resources=services,namespace=openstack-lightspeed,verbs=get;list;watch;create;patch;update;delete +// +kubebuilder:rbac:groups=networking.k8s.io,resources=networkpolicies,namespace=openstack-lightspeed,verbs=get;list;watch;create;patch +// +kubebuilder:rbac:groups=apps,resources=deployments,namespace=openstack-lightspeed,verbs=get;list;watch;create;patch +// +kubebuilder:rbac:groups="",resources=configmaps,namespace=openstack-lightspeed,verbs=get;list;watch;create;patch;delete +// +kubebuilder:rbac:groups="",resources=secrets,namespace=openstack-lightspeed,verbs=get;list;watch;create;patch;delete;deletecollection +// +kubebuilder:rbac:groups="",resources=services,namespace=openstack-lightspeed,verbs=get;list;watch;create;patch // +kubebuilder:rbac:groups="",resources=serviceaccounts,namespace=openstack-lightspeed,verbs=get;list;watch;create;patch -// +kubebuilder:rbac:groups=console.openshift.io,resources=consoleplugins,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=operator.openshift.io,resources=consoles,verbs=watch;list;get;update -// +kubebuilder:rbac:groups="",resources=persistentvolumeclaims,namespace=openstack-lightspeed,verbs=get;list;watch;create;patch;update +// +kubebuilder:rbac:groups=console.openshift.io,resources=consoleplugins,verbs=get;list;watch;create;patch;delete +// +kubebuilder:rbac:groups=operator.openshift.io,resources=consoles,verbs=get;list;watch;update +// +kubebuilder:rbac:groups="",resources=persistentvolumeclaims,namespace=openstack-lightspeed,verbs=get;list;watch;create;patch func (r *OpenStackLightspeedReconciler) Reconcile(ctx context.Context, req ctrl.Request) (result ctrl.Result, e error) { Log := r.GetLogger(ctx) @@ -355,7 +352,6 @@ func (r *OpenStackLightspeedReconciler) SetupWithManager(mgr ctrl.Manager) error // Use Build instead of Complete to get the controller reference needed by WatchDynamicCRD. c, err := ctrl.NewControllerManagedBy(mgr). For(&apiv1beta1.OpenStackLightspeed{}). - Owns(&operatorsv1alpha1.ClusterServiceVersion{}). Owns(&appsv1.Deployment{}). Owns(&corev1.ServiceAccount{}). Owns(&rbacv1.ClusterRole{}).