From 6937c1e3f7b40b8a8940f5f77cc28ae772b239eb Mon Sep 17 00:00:00 2001 From: Josh Branham Date: Fri, 3 Jul 2026 18:08:45 -0600 Subject: [PATCH] fix(clusterrole): allow system:admin (Hive) to delete protected ClusterRoles Hive uses system:admin to manage resources on target clusters. When a SyncSet is removed, Hive needs to delete the backplane-* ClusterRoles it previously created. The webhook was denying these deletions because system:admin was explicitly excluded from the system: user bypass and was not in the allowedUsers list. Co-Authored-By: Claude Opus 4.6 --- pkg/webhooks/clusterrole/clusterrole.go | 1 + pkg/webhooks/clusterrole/clusterrole_test.go | 39 +++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/pkg/webhooks/clusterrole/clusterrole.go b/pkg/webhooks/clusterrole/clusterrole.go index 9c2be77e..2a7754c8 100644 --- a/pkg/webhooks/clusterrole/clusterrole.go +++ b/pkg/webhooks/clusterrole/clusterrole.go @@ -55,6 +55,7 @@ var ( // Users allowed to delete protected ClusterRoles allowedUsers = []string{ "backplane-cluster-admin", + "system:admin", } // Groups allowed to delete protected ClusterRoles diff --git a/pkg/webhooks/clusterrole/clusterrole_test.go b/pkg/webhooks/clusterrole/clusterrole_test.go index f474d4cf..c9030826 100644 --- a/pkg/webhooks/clusterrole/clusterrole_test.go +++ b/pkg/webhooks/clusterrole/clusterrole_test.go @@ -52,6 +52,22 @@ var ( } ] }` + + // testBackplaneClusterRoleJSON represents a backplane-* protected ClusterRole + testBackplaneClusterRoleJSON = `{ + "apiVersion": "rbac.authorization.k8s.io/v1", + "kind": "ClusterRole", + "metadata": { + "name": "backplane-lpsre-admins-project" + }, + "rules": [ + { + "apiGroups": [""], + "resources": ["pods"], + "verbs": ["get", "list"] + } + ] + }` ) func runClusterRoleTests(t *testing.T, tests []ClusterRoleTestSuites) { @@ -68,9 +84,12 @@ func runClusterRoleTests(t *testing.T, tests []ClusterRoleTestSuites) { } var clusterRoleJSON string - if test.targetClusterRole == "cluster-admin" { + switch test.targetClusterRole { + case "cluster-admin": clusterRoleJSON = testClusterRoleJSON - } else { + case "backplane-lpsre-admins-project": + clusterRoleJSON = testBackplaneClusterRoleJSON + default: clusterRoleJSON = testOtherClusterRoleJSON } @@ -165,6 +184,22 @@ func TestClusterRoleDeletionPositive(t *testing.T) { shouldBeAllowed: true, targetClusterRole: "cluster-admin", }, + { + testID: "hive-system-admin-allow-backplane-role", + username: "system:admin", + userGroups: []string{"system:authenticated", "system:masters"}, + operation: admissionv1.Delete, + shouldBeAllowed: true, + targetClusterRole: "backplane-lpsre-admins-project", + }, + { + testID: "hive-system-admin-allow-protected-role", + username: "system:admin", + userGroups: []string{"system:authenticated", "system:masters"}, + operation: admissionv1.Delete, + shouldBeAllowed: true, + targetClusterRole: "cluster-admin", + }, } runClusterRoleTests(t, tests)