Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion cmd/operator-controller/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -617,7 +617,10 @@ func (c *boxcutterReconcilerConfigurator) Configure(ceReconciler *controllers.Cl
// determine if PreAuthorizer should be enabled based on feature gate
var preAuth authorization.PreAuthorizer
if features.OperatorControllerFeatureGate.Enabled(features.PreflightPermissions) {
preAuth = authorization.NewRBACPreAuthorizer(c.mgr.GetClient())
preAuth = authorization.NewRBACPreAuthorizer(
c.mgr.GetClient(),
authorization.WithNamespacedCollectionVerbs("create"),
)
}

// TODO: better scheme handling - which types do we want to support?
Expand Down
35 changes: 35 additions & 0 deletions test/e2e/features/install.feature
Original file line number Diff line number Diff line change
Expand Up @@ -535,3 +535,38 @@ Feature: Install ClusterExtension
nodeSelector:
kubernetes.io/os: linux
"""

@BoxcutterRuntime
@PreflightPermissions
Scenario: Boxcutter preflight check detects missing CREATE permissions
Given ServiceAccount "olm-sa" without create permissions is available in ${TEST_NAMESPACE}
And ClusterExtension is applied
"""
apiVersion: olm.operatorframework.io/v1
kind: ClusterExtension
metadata:
name: ${NAME}
spec:
namespace: ${TEST_NAMESPACE}
serviceAccount:
name: olm-sa
source:
sourceType: Catalog
catalog:
packageName: test
selector:
matchLabels:
"olm.operatorframework.io/metadata.name": test-catalog
"""
And ClusterExtension reports Progressing as True with Reason Retrying and Message includes:
"""
pre-authorization failed: service account requires the following permissions to manage cluster extension
"""
And ClusterExtension reports Progressing as True with Reason Retrying and Message includes:
"""
Verbs:[create]
"""
When ServiceAccount "olm-sa" with needed permissions is available in ${TEST_NAMESPACE}
Then ClusterExtension is available
And ClusterExtension reports Progressing as True with Reason Succeeded
And ClusterExtension reports Installed as True
13 changes: 13 additions & 0 deletions test/e2e/steps/steps.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ func RegisterSteps(sc *godog.ScenarioContext) {
sc.Step(`^(?i)ServiceAccount "([^"]*)" with permissions to install extensions is available in "([^"]*)" namespace$`, ServiceAccountWithNeededPermissionsIsAvailableInGivenNamespace)
sc.Step(`^(?i)ServiceAccount "([^"]*)" with needed permissions is available in test namespace$`, ServiceAccountWithNeededPermissionsIsAvailableInTestNamespace)
sc.Step(`^(?i)ServiceAccount "([^"]*)" with needed permissions is available in \${TEST_NAMESPACE}$`, ServiceAccountWithNeededPermissionsIsAvailableInTestNamespace)
sc.Step(`^(?i)ServiceAccount "([^"]*)" without create permissions is available in \${TEST_NAMESPACE}$`, ServiceAccountWithoutCreatePermissionsIsAvailableInTestNamespace)
sc.Step(`^(?i)ServiceAccount "([^"]*)" is available in \${TEST_NAMESPACE}$`, ServiceAccountIsAvailableInNamespace)
sc.Step(`^(?i)ServiceAccount "([^"]*)" in test namespace is cluster admin$`, ServiceAccountWithClusterAdminPermissionsIsAvailableInNamespace)
sc.Step(`^(?i)ServiceAccount "([^"]+)" in test namespace has permissions to fetch "([^"]+)" metrics$`, ServiceAccountWithFetchMetricsPermissions)
Expand Down Expand Up @@ -877,6 +878,18 @@ func ServiceAccountWithNeededPermissionsIsAvailableInTestNamespace(ctx context.C
return applyPermissionsToServiceAccount(ctx, serviceAccount, rbacTemplate)
}

// ServiceAccountWithoutCreatePermissionsIsAvailableInTestNamespace creates a ServiceAccount with permissions that
// intentionally exclude the "create" verb to test preflight permission validation for Boxcutter applier.
// This is used to verify that the preflight check properly detects missing CREATE permissions.
func ServiceAccountWithoutCreatePermissionsIsAvailableInTestNamespace(ctx context.Context, serviceAccount string) error {
kernel := "helm"
if enabled, found := featureGates[features.BoxcutterRuntime]; found && enabled {
kernel = "boxcutter"
}
rbacTemplate := fmt.Sprintf("%s-%s-no-create-rbac-template.yaml", serviceAccount, kernel)
return applyPermissionsToServiceAccount(ctx, serviceAccount, rbacTemplate)
}

// ServiceAccountWithNeededPermissionsIsAvailableInGivenNamespace creates a ServiceAccount and enables creation of any cluster extension on behalf of this account.
func ServiceAccountWithNeededPermissionsIsAvailableInGivenNamespace(ctx context.Context, serviceAccount string, ns string) error {
sc := scenarioCtx(ctx)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: ${TEST_NAMESPACE}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: ${TEST_NAMESPACE}-${SERVICEACCOUNT_NAME}-olm-admin-clusterrole
rules:
# Allow management of ClusterExtensionRevision finalizers (e.g. by the Boxcutter applier)
- apiGroups: [olm.operatorframework.io]
resources: [clusterextensionrevisions/finalizers]
verbs: [update, patch]
# OLMv0 compatibility requirement for AllNamespaces install
# https://github.com/operator-framework/operator-lifecycle-manager/blob/dfd0b2bea85038d3c0d65348bc812d297f16b8d2/pkg/controller/operators/olm/operatorgroup.go#L530
- apiGroups: [ "" ]
resources:
- namespaces
verbs: [ get, list, watch ]
# Bundle resource management RBAC derived from bundle resource and permissions described in the ClusterServiceVersion
# NOTE: Intentionally MISSING "create" verb to test preflight check
- apiGroups: [apiextensions.k8s.io]
resources: [customresourcedefinitions]
verbs: [update, get, delete, patch]
- apiGroups: [""]
resources:
- configmaps
- serviceaccounts
verbs: [update, list, watch, get, delete, patch]
- apiGroups: [ "" ]
resources:
- events
verbs: [ patch ]
- apiGroups: ["apps"]
resources:
- deployments
verbs: [ update, get, delete, patch ]
- apiGroups: ["networking.k8s.io"]
resources:
- networkpolicies
verbs: [update, list, get, delete, patch]
- apiGroups: ["rbac.authorization.k8s.io"]
resources:
- clusterroles
- roles
- clusterrolebindings
- rolebindings
verbs: [ update, get, delete, patch ]
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: [update, list, watch, get, delete, patch]
- apiGroups: ["authorization.k8s.io"]
resources: ["subjectaccessreviews"]
verbs: [create]
- apiGroups: ["authentication.k8s.io"]
resources: ["tokenreviews"]
verbs: [create]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: ${TEST_NAMESPACE}-${SERVICEACCOUNT_NAME}-install-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ${TEST_NAMESPACE}-${SERVICEACCOUNT_NAME}-olm-admin-clusterrole
subjects:
- kind: ServiceAccount
name: ${SERVICEACCOUNT_NAME}
namespace: ${TEST_NAMESPACE}
68 changes: 68 additions & 0 deletions test/e2e/steps/testdata/olm-sa-helm-no-create-rbac-template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: ${TEST_NAMESPACE}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: ${TEST_NAMESPACE}-${SERVICEACCOUNT_NAME}-olm-admin-clusterrole
rules:
- apiGroups: [olm.operatorframework.io]
resources: [clusterextensions, clusterextensions/finalizers]
resourceNames: ["${CLUSTEREXTENSION_NAME}"]
verbs: [update]
# Bundle resource management RBAC derived from bundle resource and permissions described in the ClusterServiceVersion
# NOTE: Intentionally MISSING "create" verb to test preflight check
- apiGroups: [apiextensions.k8s.io]
resources: [customresourcedefinitions]
verbs: [update, list, watch, get, delete, patch]
- apiGroups: [""]
resources:
- configmaps
- secrets
- services
- serviceaccounts
- events
- namespaces
- persistentvolumes
- persistentvolumeclaims
verbs: [update, list, watch, get, delete, patch]
- apiGroups: ["apps"]
resources:
- deployments
verbs: [ update, list, watch, get, delete, patch ]
- apiGroups: ["networking.k8s.io"]
resources:
- networkpolicies
verbs: [ update, list, watch, get, delete, patch ]
- apiGroups: ["rbac.authorization.k8s.io"]
resources:
- clusterroles
- roles
- clusterrolebindings
- rolebindings
verbs: [ update, list, watch, get, delete, patch ]
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: [ update, list, watch, get, delete, patch ]
- apiGroups: ["authorization.k8s.io"]
resources: ["subjectaccessreviews"]
verbs: [create]
- apiGroups: ["authentication.k8s.io"]
resources: ["tokenreviews"]
verbs: [create]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: ${TEST_NAMESPACE}-${SERVICEACCOUNT_NAME}-install-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ${TEST_NAMESPACE}-${SERVICEACCOUNT_NAME}-olm-admin-clusterrole
subjects:
- kind: ServiceAccount
name: ${SERVICEACCOUNT_NAME}
namespace: ${TEST_NAMESPACE}
Loading