From 581128966c962d73ba385fe32d45843cc68cd56b Mon Sep 17 00:00:00 2001 From: "Per G. da Silva" Date: Mon, 9 Mar 2026 17:18:36 +0100 Subject: [PATCH] Use dedicated least-privilege service accounts for revision probe e2e tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The revision probe e2e tests previously shared the generic `olm-sa` service account, which had broad permissions that masked potential RBAC issues. This change: - Refactors RBAC template selection to use a convention-based naming pattern: `--rbac-template.yaml`, replacing the hardcoded constants with `fmt.Sprintf` - Renames existing RBAC templates with `olm-sa-` prefix to follow the new convention (`rbac-template.yaml` → `olm-sa-helm-rbac-template.yaml`, `boxcutter-rbac-template.yaml` → `olm-sa-boxcutter-rbac-template.yaml`) - Introduces a dedicated `pvc-probe-sa` service account for PVC probe scenarios with a least-privilege RBAC template granting only CER finalizer update, PersistentVolume CRUD, PVC CRUD, and ConfigMap CRUD Signed-off-by: Per G. da Silva --- test/e2e/features/revision.feature | 9 ++-- test/e2e/steps/steps.go | 11 ++-- ...ml => olm-sa-boxcutter-rbac-template.yaml} | 0 ...te.yaml => olm-sa-helm-rbac-template.yaml} | 0 .../pvc-probe-sa-boxcutter-rbac-template.yaml | 51 +++++++++++++++++++ 5 files changed, 60 insertions(+), 11 deletions(-) rename test/e2e/steps/testdata/{boxcutter-rbac-template.yaml => olm-sa-boxcutter-rbac-template.yaml} (100%) rename test/e2e/steps/testdata/{rbac-template.yaml => olm-sa-helm-rbac-template.yaml} (100%) create mode 100644 test/e2e/steps/testdata/pvc-probe-sa-boxcutter-rbac-template.yaml diff --git a/test/e2e/features/revision.feature b/test/e2e/features/revision.feature index 0018bb78f..2d9126630 100644 --- a/test/e2e/features/revision.feature +++ b/test/e2e/features/revision.feature @@ -5,16 +5,16 @@ Feature: Install ClusterExtensionRevision Background: Given OLM is available - And ServiceAccount "olm-sa" with needed permissions is available in ${TEST_NAMESPACE} - Scenario: Probe failure for PersistentVolumeClaim halts phase progression + Scenario: Probe failure for PersistentVolumeClaim halts phase progression + Given ServiceAccount "pvc-probe-sa" with needed permissions is available in test namespace When ClusterExtensionRevision is applied """ apiVersion: olm.operatorframework.io/v1 kind: ClusterExtensionRevision metadata: annotations: - olm.operatorframework.io/service-account-name: olm-sa + olm.operatorframework.io/service-account-name: pvc-probe-sa olm.operatorframework.io/service-account-namespace: ${TEST_NAMESPACE} name: ${CER_NAME} spec: @@ -59,13 +59,14 @@ Feature: Install ClusterExtensionRevision And resource "configmap/test-configmap" is not installed Scenario: Phases progress when PersistentVolumeClaim becomes "Bound" + Given ServiceAccount "pvc-probe-sa" with needed permissions is available in test namespace When ClusterExtensionRevision is applied """ apiVersion: olm.operatorframework.io/v1 kind: ClusterExtensionRevision metadata: annotations: - olm.operatorframework.io/service-account-name: olm-sa + olm.operatorframework.io/service-account-name: pvc-probe-sa olm.operatorframework.io/service-account-namespace: ${TEST_NAMESPACE} name: ${CER_NAME} spec: diff --git a/test/e2e/steps/steps.go b/test/e2e/steps/steps.go index 6f9d2a894..fd5ac1211 100644 --- a/test/e2e/steps/steps.go +++ b/test/e2e/steps/steps.go @@ -44,9 +44,6 @@ const ( olmDeploymentName = "operator-controller-controller-manager" timeout = 5 * time.Minute tick = 1 * time.Second - - helmRBACTemplate = "rbac-template.yaml" - boxcutterRBACTemplate = "boxcutter-rbac-template.yaml" ) var ( @@ -833,13 +830,13 @@ func ServiceAccountIsAvailableInNamespace(ctx context.Context, serviceAccount st } // ServiceAccountWithNeededPermissionsIsAvailableInNamespace creates a ServiceAccount and applies standard RBAC permissions. -// The RBAC template is selected based on the BoxcutterRuntime feature gate: the boxcutter applier does not require -// cluster-scoped list/watch permissions, so a narrower template is used when BoxcutterRuntime is enabled. +// The RBAC template is selected based on the service account and BoxcutterRuntime feature gate: --rbac-template.yaml func ServiceAccountWithNeededPermissionsIsAvailableInNamespace(ctx context.Context, serviceAccount string) error { - rbacTemplate := helmRBACTemplate + kernel := "helm" if enabled, found := featureGates[features.BoxcutterRuntime]; found && enabled { - rbacTemplate = boxcutterRBACTemplate + kernel = "boxcutter" } + rbacTemplate := fmt.Sprintf("%s-%s-rbac-template.yaml", serviceAccount, kernel) return applyPermissionsToServiceAccount(ctx, serviceAccount, rbacTemplate) } diff --git a/test/e2e/steps/testdata/boxcutter-rbac-template.yaml b/test/e2e/steps/testdata/olm-sa-boxcutter-rbac-template.yaml similarity index 100% rename from test/e2e/steps/testdata/boxcutter-rbac-template.yaml rename to test/e2e/steps/testdata/olm-sa-boxcutter-rbac-template.yaml diff --git a/test/e2e/steps/testdata/rbac-template.yaml b/test/e2e/steps/testdata/olm-sa-helm-rbac-template.yaml similarity index 100% rename from test/e2e/steps/testdata/rbac-template.yaml rename to test/e2e/steps/testdata/olm-sa-helm-rbac-template.yaml diff --git a/test/e2e/steps/testdata/pvc-probe-sa-boxcutter-rbac-template.yaml b/test/e2e/steps/testdata/pvc-probe-sa-boxcutter-rbac-template.yaml new file mode 100644 index 000000000..8dceb2478 --- /dev/null +++ b/test/e2e/steps/testdata/pvc-probe-sa-boxcutter-rbac-template.yaml @@ -0,0 +1,51 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: ${TEST_NAMESPACE}-${SERVICEACCOUNT_NAME}-clusterrole +rules: + - apiGroups: [olm.operatorframework.io] + resources: [clusterextensionrevisions/finalizers] + verbs: [update] + - apiGroups: [""] + resources: [persistentvolumes] + verbs: [create, update, get, delete, patch] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: ${TEST_NAMESPACE}-${SERVICEACCOUNT_NAME}-role + namespace: ${TEST_NAMESPACE} +rules: + - apiGroups: [""] + resources: [persistentvolumeclaims] + verbs: [create, update, get, delete, patch] + - apiGroups: [""] + resources: [configmaps] + verbs: [create, update, get, delete, patch] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: ${TEST_NAMESPACE}-${SERVICEACCOUNT_NAME}-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: ${TEST_NAMESPACE}-${SERVICEACCOUNT_NAME}-clusterrole +subjects: + - kind: ServiceAccount + name: ${SERVICEACCOUNT_NAME} + namespace: ${TEST_NAMESPACE} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: ${TEST_NAMESPACE}-${SERVICEACCOUNT_NAME}-binding + namespace: ${TEST_NAMESPACE} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: ${TEST_NAMESPACE}-${SERVICEACCOUNT_NAME}-role +subjects: + - kind: ServiceAccount + name: ${SERVICEACCOUNT_NAME} + namespace: ${TEST_NAMESPACE}