From f55959306be912e54afb027c1bbd882a76e8e3a9 Mon Sep 17 00:00:00 2001 From: Brian McMahon Date: Mon, 11 May 2026 15:09:44 -0700 Subject: [PATCH] Add RBAC for the new ui-apis ManagedCluster / ClusterInformation handlers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The cloud security fix in calico-private (PR #11546) moves UISettings delete, ManagedCluster CRUD, and ClusterInformation reads off the user-impersonated /apis/projectcalico.org/v3 proxy path and onto ui-apis handlers that call the Calico API with their own service-account token. The tigera-manager pod SA therefore needs new grants on these resources. Changes to managerClusterRole (pkg/render/manager.go): - uisettings / uisettingsgroups / uisettingsgroups/data — add "delete" (previously only get/list/watch). - managedclusters — add "create" and "delete" verbs (previously only get/list/watch). "update" continues to live in managedClustersUpdateRBAC(). - clusterinformations — new rule with "get" and "list" so the UI can surface the management cluster version through ui-apis. manager_test.go updated at both assertion sites to match. Co-Authored-By: Claude Opus 4.7 (1M context) --- pkg/render/manager.go | 20 ++++++++++++++++---- pkg/render/manager_test.go | 18 ++++++++++++++---- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/pkg/render/manager.go b/pkg/render/manager.go index ecbf2cae00..47ebd9394c 100644 --- a/pkg/render/manager.go +++ b/pkg/render/manager.go @@ -999,14 +999,23 @@ func managerClusterRole(managedCluster bool, kubernetesProvider operatorv1.Provi { // ui-apis needs broad read access to UISettings and UISettingsGroups to serve // requests on behalf of users. It performs SubjectAccessReviews to enforce - // per-group RBAC before returning results. + // per-group RBAC before returning results. Delete is included because the + // ui-apis DELETE handler issues the call with its own service-account token + // (writes were moved off user impersonation by the cloud security fix). APIGroups: []string{"projectcalico.org"}, Resources: []string{ "uisettings", "uisettingsgroups", "uisettingsgroups/data", }, - Verbs: []string{"get", "list", "watch"}, + Verbs: []string{"get", "list", "watch", "delete"}, + }, + { + // ClusterInformation read: surfaces the management-cluster version in the UI. + // Served by the ui-apis ClusterInformation handler using its own SA token. + APIGroups: []string{"projectcalico.org"}, + Resources: []string{"clusterinformations"}, + Verbs: []string{"get", "list"}, }, { APIGroups: []string{"projectcalico.org"}, @@ -1030,11 +1039,14 @@ func managerClusterRole(managedCluster bool, kubernetesProvider operatorv1.Provi }, Verbs: []string{"list"}, }, - // Allow Enterprise Custom Dashboards to access managed clusters + // Allow Enterprise Custom Dashboards to access managed clusters. Create/delete + // were added when the ui-apis ManagedCluster handler took over CRUD with its + // own SA token (replacing the impersonated /apis/.../managedclusters proxy). + // Update is granted separately via managedClustersUpdateRBAC(). { APIGroups: []string{"projectcalico.org"}, Resources: []string{"managedclusters"}, - Verbs: []string{"get", "list", "watch"}, + Verbs: []string{"get", "list", "watch", "create", "delete"}, }, { APIGroups: []string{"projectcalico.org"}, diff --git a/pkg/render/manager_test.go b/pkg/render/manager_test.go index 92243e464d..64a8da60e7 100644 --- a/pkg/render/manager_test.go +++ b/pkg/render/manager_test.go @@ -354,7 +354,12 @@ var _ = Describe("Tigera Secure Manager rendering tests", func() { "uisettingsgroups", "uisettingsgroups/data", }, - Verbs: []string{"get", "list", "watch"}, + Verbs: []string{"get", "list", "watch", "delete"}, + }, + { + APIGroups: []string{"projectcalico.org"}, + Resources: []string{"clusterinformations"}, + Verbs: []string{"get", "list"}, }, { APIGroups: []string{"projectcalico.org"}, @@ -381,7 +386,7 @@ var _ = Describe("Tigera Secure Manager rendering tests", func() { { APIGroups: []string{"projectcalico.org"}, Resources: []string{"managedclusters"}, - Verbs: []string{"get", "list", "watch"}, + Verbs: []string{"get", "list", "watch", "create", "delete"}, }, { APIGroups: []string{"projectcalico.org"}, @@ -684,7 +689,12 @@ var _ = Describe("Tigera Secure Manager rendering tests", func() { "uisettingsgroups", "uisettingsgroups/data", }, - Verbs: []string{"get", "list", "watch"}, + Verbs: []string{"get", "list", "watch", "delete"}, + }, + { + APIGroups: []string{"projectcalico.org"}, + Resources: []string{"clusterinformations"}, + Verbs: []string{"get", "list"}, }, { APIGroups: []string{"projectcalico.org"}, @@ -711,7 +721,7 @@ var _ = Describe("Tigera Secure Manager rendering tests", func() { { APIGroups: []string{"projectcalico.org"}, Resources: []string{"managedclusters"}, - Verbs: []string{"get", "list", "watch"}, + Verbs: []string{"get", "list", "watch", "create", "delete"}, }, { APIGroups: []string{"projectcalico.org"},