Repository: operator-framework/operator-lifecycle-manager
Pull request #3206 (2024-04-19 15:40:45)

OCPBUGS-29729: Updates default security context behavior for catalog source pods
<!--

Before making a PR, please read our contributing guidelines https://github.com/operator-framework/operator-lifecycle-manager/blob/master/CONTRIBUTING.md

Note: Make sure your branch is rebased to the latest upstream master.

-->

**Description of the change:**
Before: by default CatalogSource would stamp out pods with the "legacy" security profile
Now: by default CatalogSource stamps out "restricted" security profile pods when in appropriately labeled namespaces and "legacy" otherwise

**Motivation for the change:**
Helps users be secure-by-default on PSA clusters when deploying in  "restricted" namespaces (no change for older clusters)

**Architectural changes:**

<!--
If necessary, briefly describe any architectural changes, other options considered, and/or link to any EPs or design docs
-->

**Testing remarks:**

<!--
Call out any information around how you've tested the code change that may be useful for reviewers. For instance:
 * any edge-cases you have (dis)covered
 * how you have reproduced and tested for regressions in bug fixes
 * how you've tested for flakes in e2e tests or flake fixes
-->

**Reviewer Checklist**
- [ ] Implementation matches the proposed design, or proposal is updated to match implementation
- [ ] Sufficient unit test coverage
- [ ] Sufficient end-to-end test coverage
- [ ] Bug fixes are accompanied by regression test(s)
- [ ] e2e tests and flake fixes are accompanied evidence of flake testing, e.g. executing the test 100(0) times
- [ ] tech debt/todo is accompanied by issue link(s) in comments in the surrounding code
- [ ] Tests are comprehensible, e.g. Ginkgo DSL is being used appropriately
- [ ] Docs updated or added to `/doc`
- [ ] Commit messages sensible and descriptive
- [ ] Tests marked as `[FLAKE]` are truly flaky and have an issue
- [ ] Code is properly formatted


<!--

Note: If this PR is fixing an issue make sure to add a note saying:
Closes #<ISSUE_NUMBER>

-->


bentito: This PR is a positive step towards better handling of security contexts in the OLM pod reconciler, making it easier to manage and test security configurations comprehensively. LGTM

Patch:
diff --git a/Dockerfile b/Dockerfile
index c4bc9e22b..63510a57d 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -2,11 +2,11 @@ FROM quay.io/fedora/fedora:37-x86_64 as builder
 LABEL stage=builder
 WORKDIR /build
 
-# install dependencies and go 1.21
+# install dependencies and go 1.22
 
 # copy just enough of the git repo to parse HEAD, used to record version in OLM binaries
 RUN dnf update -y && dnf install -y bash make git mercurial jq wget && dnf upgrade -y
-RUN curl -sSL https://go.dev/dl/go1.21.9.linux-amd64.tar.gz | tar -xzf - -C /usr/local
+RUN curl -sSL https://go.dev/dl/go1.22.2.linux-amd64.tar.gz | tar -xzf - -C /usr/local
 ENV PATH=/usr/local/go/bin:$PATH
 COPY .git/HEAD .git/HEAD
 COPY .git/refs/heads/. .git/refs/heads
diff --git a/go.mod b/go.mod
index 5bfd4e08d..4efa8730a 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,8 @@
 module github.com/operator-framework/operator-lifecycle-manager
 
-go 1.21
+go 1.22.0
+
+toolchain go1.22.2
 
 require (
 	github.com/blang/semver/v4 v4.0.0
diff --git a/pkg/controller/registry/reconciler/configmap.go b/pkg/controller/registry/reconciler/configmap.go
index 654484125..2e47c5650 100644
--- a/pkg/controller/registry/reconciler/configmap.go
+++ b/pkg/controller/registry/reconciler/configmap.go
@@ -109,8 +109,8 @@ func (s *configMapCatalogSourceDecorator) Service() (*corev1.Service, error) {
 	return svc, nil
 }
 
-func (s *configMapCatalogSourceDecorator) Pod(image string) (*corev1.Pod, error) {
-	pod, err := Pod(s.CatalogSource, "configmap-registry-server", "", "", image, nil, s.Labels(), s.Annotations(), 5, 5, s.runAsUser)
+func (s *configMapCatalogSourceDecorator) Pod(image string, defaultPodSecurityConfig v1alpha1.SecurityConfig) (*corev1.Pod, error) {
+	pod, err := Pod(s.CatalogSource, "configmap-registry-server", "", "", image, nil, s.Labels(), s.Annotations(), 5, 5, s.runAsUser, defaultPodSecurityConfig)
 	if err != nil {
 		return nil, err
 	}
@@ -238,8 +238,8 @@ func (c *ConfigMapRegistryReconciler) currentRoleBinding(source configMapCatalog
 	return roleBinding
 }
 
-func (c *ConfigMapRegistryReconciler) currentPods(source configMapCatalogSourceDecorator, image string) ([]*corev1.Pod, error) {
-	protoPod, err := source.Pod(image)
+func (c *ConfigMapRegistryReconciler) currentPods(source configMapCatalogSourceDecorator, image string, defaultPodSecurityConfig v1alpha1.SecurityConfig) ([]*corev1.Pod, error) {
+	protoPod, err := source.Pod(image, defaultPodSecurityConfig)
 	if err != nil {
 		return nil, err
 	}
@@ -255,8 +255,8 @@ func (c *ConfigMapRegistryReconciler) currentPods(source configMapCatalogSourceD
 	return pods, nil
 }
 
-func (c *ConfigMapRegistryReconciler) currentPodsWithCorrectResourceVersion(source configMapCatalogSourceDecorator, image string) ([]*corev1.Pod, error) {
-	protoPod, err := source.Pod(image)
+func (c *ConfigMapRegistryReconciler) currentPodsWithCorrectResourceVersion(source configMapCatalogSourceDecorator, image string, defaultPodSecurityConfig v1alpha1.SecurityConfig) ([]*corev1.Pod, error) {
+	protoPod, err := source.Pod(image, defaultPodSecurityConfig)
 	if err != nil {
 		return nil, err
 	}
@@ -288,6 +288,11 @@ func (c *ConfigMapRegistryReconciler) EnsureRegistryServer(logger *logrus.Entry,
 	overwrite := source.Status.RegistryServiceStatus == nil
 	overwritePod := overwrite
 
+	defaultPodSecurityConfig, err := getDefaultPodContextConfig(c.OpClient, catalogSource.GetNamespace())
+	if err != nil {
+		return err
+	}
+
 	if source.Spec.SourceType == v1alpha1.SourceTypeConfigmap || source.Spec.SourceType == v1alpha1.SourceTypeInternal {
 		// fetch configmap first, exit early if we can't find it
 		// we use the live client here instead of a lister since our listers are scoped to objects with the olm.managed label,
@@ -311,7 +316,7 @@ func (c *ConfigMapRegistryReconciler) EnsureRegistryServer(logger *logrus.Entry,
 		}
 
 		// recreate the pod if no existing pod is serving the latest image
-		current, err := c.currentPodsWithCorrectResourceVersion(source, image)
+		current, err := c.currentPodsWithCorrectResourceVersion(source, image, defaultPodSecurityConfig)
 		if err != nil {
 			return err
 		}
@@ -330,11 +335,11 @@ func (c *ConfigMapRegistryReconciler) EnsureRegistryServer(logger *logrus.Entry,
 	if err := c.ensureRoleBinding(source, overwrite); err != nil {
 		return errors.Wrapf(err, "error ensuring rolebinding: %s", source.RoleBinding().GetName())
 	}
-	pod, err := source.Pod(image)
+	pod, err := source.Pod(image, defaultPodSecurityConfig)
 	if err != nil {
 		return err
 	}
-	if err := c.ensurePod(source, overwritePod); err != nil {
+	if err := c.ensurePod(source, defaultPodSecurityConfig, overwritePod); err != nil {
 		return errors.Wrapf(err, "error ensuring pod: %s", pod.GetName())
 	}
 	service, err := source.Service()
@@ -400,12 +405,12 @@ func (c *ConfigMapRegistryReconciler) ensureRoleBinding(source configMapCatalogS
 	return err
 }
 
-func (c *ConfigMapRegistryReconciler) ensurePod(source configMapCatalogSourceDecorator, overwrite bool) error {
-	pod, err := source.Pod(c.Image)
+func (c *ConfigMapRegistryReconciler) ensurePod(source configMapCatalogSourceDecorator, defaultPodSecurityConfig v1alpha1.SecurityConfig, overwrite bool) error {
+	pod, err := source.Pod(c.Image, defaultPodSecurityConfig)
 	if err != nil {
 		return err
 	}
-	currentPods, err := c.currentPods(source, c.Image)
+	currentPods, err := c.currentPods(source, c.Image, defaultPodSecurityConfig)
 	if err != nil {
 		return err
 	}
@@ -460,6 +465,11 @@ func (c *ConfigMapRegistryReconciler) CheckRegistryServer(logger *logrus.Entry,
 		return
 	}
 
+	defaultPodSecurityConfig, err := getDefaultPodContextConfig(c.OpClient, catalogSource.GetNamespace())
+	if err != nil {
+		return false, err
+	}
+
 	if source.Spec.SourceType == v1alpha1.SourceTypeConfigmap || source.Spec.SourceType == v1alpha1.SourceTypeInternal {
 		// we use the live client here instead of a lister since our listers are scoped to objects with the olm.managed label,
 		// and this configmap is a user-provided input to the catalog source and will not have that label
@@ -473,7 +483,7 @@ func (c *ConfigMapRegistryReconciler) CheckRegistryServer(logger *logrus.Entry,
 		}
 
 		// recreate the pod if no existing pod is serving the latest image
-		current, err := c.currentPodsWithCorrectResourceVersion(source, image)
+		current, err := c.currentPodsWithCorrectResourceVersion(source, image, defaultPodSecurityConfig)
 		if err != nil {
 			return false, err
 		}
@@ -489,7 +499,7 @@ func (c *ConfigMapRegistryReconciler) CheckRegistryServer(logger *logrus.Entry,
 	if err != nil {
 		return false, err
 	}
-	pods, err := c.currentPods(source, c.Image)
+	pods, err := c.currentPods(source, c.Image, defaultPodSecurityConfig)
 	if err != nil {
 		return false, err
 	}
diff --git a/pkg/controller/registry/reconciler/grpc.go b/pkg/controller/registry/reconciler/grpc.go
index 498160025..30cf12f1d 100644
--- a/pkg/controller/registry/reconciler/grpc.go
+++ b/pkg/controller/registry/reconciler/grpc.go
@@ -10,6 +10,13 @@ import (
 
 	"github.com/google/go-cmp/cmp"
 	"github.com/operator-framework/api/pkg/operators/v1alpha1"
+
+	"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install"
+	controllerclient "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/controller-runtime/client"
+	hashutil "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/util/hash"
+	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
+	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister"
+	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil"
 	pkgerrors "github.com/pkg/errors"
 	"github.com/sirupsen/logrus"
 	corev1 "k8s.io/api/core/v1"
@@ -18,13 +25,6 @@ import (
 	"k8s.io/apimachinery/pkg/labels"
 	"k8s.io/apimachinery/pkg/util/intstr"
 	"k8s.io/utils/ptr"
-
-	"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install"
-	controllerclient "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/controller-runtime/client"
-	hashutil "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/util/hash"
-	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
-	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister"
-	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil"
 )
 
 const (
@@ -134,8 +134,8 @@ func (s *grpcCatalogSourceDecorator) ServiceAccount() *corev1.ServiceAccount {
 	}
 }
 
-func (s *grpcCatalogSourceDecorator) Pod(serviceAccount *corev1.ServiceAccount) (*corev1.Pod, error) {
-	pod, err := Pod(s.CatalogSource, "registry-server", s.opmImage, s.utilImage, s.Spec.Image, serviceAccount, s.Labels(), s.Annotations(), 5, 10, s.createPodAsUser)
+func (s *grpcCatalogSourceDecorator) Pod(serviceAccount *corev1.ServiceAccount, defaultPodSecurityConfig v1alpha1.SecurityConfig) (*corev1.Pod, error) {
+	pod, err := Pod(s.CatalogSource, "registry-server", s.opmImage, s.utilImage, s.Spec.Image, serviceAccount, s.Labels(), s.Annotations(), 5, 10, s.createPodAsUser, defaultPodSecurityConfig)
 	if err != nil {
 		return nil, err
 	}
@@ -203,7 +203,7 @@ func (c *GrpcRegistryReconciler) currentUpdatePods(logger *logrus.Entry, source
 	return pods
 }
 
-func (c *GrpcRegistryReconciler) currentPodsWithCorrectImageAndSpec(logger *logrus.Entry, source grpcCatalogSourceDecorator, serviceAccount *corev1.ServiceAccount) ([]*corev1.Pod, error) {
+func (c *GrpcRegistryReconciler) currentPodsWithCorrectImageAndSpec(logger *logrus.Entry, source grpcCatalogSourceDecorator, serviceAccount *corev1.ServiceAccount, defaultPodSecurityConfig v1alpha1.SecurityConfig) ([]*corev1.Pod, error) {
 	logger.Info("searching for current pods")
 	pods, err := c.Lister.CoreV1().PodLister().Pods(source.GetNamespace()).List(labels.SelectorFromValidatedSet(source.Labels()))
 	if err != nil {
@@ -211,7 +211,7 @@ func (c *GrpcRegistryReconciler) currentPodsWithCorrectImageAndSpec(logger *logr
 		return nil, nil
 	}
 	found := []*corev1.Pod{}
-	newPod, err := source.Pod(serviceAccount)
+	newPod, err := source.Pod(serviceAccount, defaultPodSecurityConfig)
 	if err != nil {
 		return nil, err
 	}
@@ -273,8 +273,13 @@ func (c *GrpcRegistryReconciler) EnsureRegistryServer(logger *logrus.Entry, cata
 		return err
 	}
 
+	defaultPodSecurityConfig, err := getDefaultPodContextConfig(c.OpClient, catalogSource.GetNamespace())
+	if err != nil {
+		return err
+	}
+
 	// recreate the pod if no existing pod is serving the latest image or correct spec
-	current, err := c.currentPodsWithCorrectImageAndSpec(logger, source, sa)
+	current, err := c.currentPodsWithCorrectImageAndSpec(logger, source, sa, defaultPodSecurityConfig)
 	if err != nil {
 		return err
 	}
@@ -283,14 +288,14 @@ func (c *GrpcRegistryReconciler) EnsureRegistryServer(logger *logrus.Entry, cata
 		logger.Info("registry pods invalid, need to overwrite")
 	}
 
-	pod, err := source.Pod(sa)
+	pod, err := source.Pod(sa, defaultPodSecurityConfig)
 	if err != nil {
 		return err
 	}
-	if err := c.ensurePod(logger, source, sa, overwritePod); err != nil {
+	if err := c.ensurePod(logger, source, sa, defaultPodSecurityConfig, overwritePod); err != nil {
 		return pkgerrors.Wrapf(err, "error ensuring pod: %s", pod.GetName())
 	}
-	if err := c.ensureUpdatePod(logger, sa, source); err != nil {
+	if err := c.ensureUpdatePod(logger, sa, defaultPodSecurityConfig, source); err != nil {
 		if _, ok := err.(UpdateNotReadyErr); ok {
 			return err
 		}
@@ -340,7 +345,7 @@ func isRegistryServiceStatusValid(source *grpcCatalogSourceDecorator) (bool, err
 	return true, nil
 }
 
-func (c *GrpcRegistryReconciler) ensurePod(logger *logrus.Entry, source grpcCatalogSourceDecorator, serviceAccount *corev1.ServiceAccount, overwrite bool) error {
+func (c *GrpcRegistryReconciler) ensurePod(logger *logrus.Entry, source grpcCatalogSourceDecorator, serviceAccount *corev1.ServiceAccount, defaultPodSecurityConfig v1alpha1.SecurityConfig, overwrite bool) error {
 	// currentPods refers to the current pod instances of the catalog source
 	currentPods := c.currentPods(logger, source)
 
@@ -373,7 +378,7 @@ func (c *GrpcRegistryReconciler) ensurePod(logger *logrus.Entry, source grpcCata
 			}
 		}
 	}
-	desiredPod, err := source.Pod(serviceAccount)
+	desiredPod, err := source.Pod(serviceAccount, defaultPodSecurityConfig)
 	if err != nil {
 		return err
 	}
@@ -387,7 +392,7 @@ func (c *GrpcRegistryReconciler) ensurePod(logger *logrus.Entry, source grpcCata
 }
 
 // ensureUpdatePod checks that for the same catalog source version the same container imageID is running
-func (c *GrpcRegistryReconciler) ensureUpdatePod(logger *logrus.Entry, serviceAccount *corev1.ServiceAccount, source grpcCatalogSourceDecorator) error {
+func (c *GrpcRegistryReconciler) ensureUpdatePod(logger *logrus.Entry, serviceAccount *corev1.ServiceAccount, podSecurityConfig v1alpha1.SecurityConfig, source grpcCatalogSourceDecorator) error {
 	if !source.Poll() {
 		logger.Info("polling not enabled, no update pod will be created")
 		return nil
@@ -398,7 +403,7 @@ func (c *GrpcRegistryReconciler) ensureUpdatePod(logger *logrus.Entry, serviceAc
 
 	if source.Update() && len(currentUpdatePods) == 0 {
 		logger.Infof("catalog update required at %s", time.Now().String())
-		pod, err := c.createUpdatePod(source, serviceAccount)
+		pod, err := c.createUpdatePod(source, serviceAccount, podSecurityConfig)
 		if err != nil {
 			return pkgerrors.Wrapf(err, "creating update catalog source pod")
 		}
@@ -506,9 +511,9 @@ func ServiceHashMatch(existing, new *corev1.Service) bool {
 }
 
 // createUpdatePod is an internal method that creates a pod using the latest catalog source.
-func (c *GrpcRegistryReconciler) createUpdatePod(source grpcCatalogSourceDecorator, serviceAccount *corev1.ServiceAccount) (*corev1.Pod, error) {
+func (c *GrpcRegistryReconciler) createUpdatePod(source grpcCatalogSourceDecorator, serviceAccount *corev1.ServiceAccount, defaultPodSecurityConfig v1alpha1.SecurityConfig) (*corev1.Pod, error) {
 	// remove label from pod to ensure service does not accidentally route traffic to the pod
-	p, err := source.Pod(serviceAccount)
+	p, err := source.Pod(serviceAccount, defaultPodSecurityConfig)
 	if err != nil {
 		return nil, err
 	}
@@ -612,13 +617,18 @@ func (c *GrpcRegistryReconciler) CheckRegistryServer(logger *logrus.Entry, catal
 		return false, nil
 	}
 
+	registryPodSecurityConfig, err := getDefaultPodContextConfig(c.OpClient, catalogSource.GetNamespace())
+	if err != nil {
+		return false, err
+	}
+
 	// Check on registry resources
 	// TODO: add gRPC health check
 	service, err := c.currentService(source)
 	if err != nil {
 		return false, err
 	}
-	current, err := c.currentPodsWithCorrectImageAndSpec(logger, source, serviceAccount)
+	current, err := c.currentPodsWithCorrectImageAndSpec(logger, source, serviceAccount, registryPodSecurityConfig)
 	if err != nil {
 		return false, err
 	}
diff --git a/pkg/controller/registry/reconciler/reconciler.go b/pkg/controller/registry/reconciler/reconciler.go
index 77b509603..0b0402cc3 100644
--- a/pkg/controller/registry/reconciler/reconciler.go
+++ b/pkg/controller/registry/reconciler/reconciler.go
@@ -2,6 +2,7 @@
 package reconciler
 
 import (
+	"context"
 	"fmt"
 	"path/filepath"
 
@@ -29,7 +30,7 @@ const (
 	CatalogPriorityClassKey string = "operatorframework.io/priorityclass"
 	// PodHashLabelKey is the key of a label for podspec hash information
 	PodHashLabelKey = "olm.pod-spec-hash"
-	//ClusterAutoscalingAnnotation is the annotation that enables the cluster autoscaler to evict catalog pods
+	//ClusterAutoscalingAnnotationKey is the annotation that enables the cluster autoscaler to evict catalog pods
 	ClusterAutoscalingAnnotationKey string = "cluster-autoscaler.kubernetes.io/safe-to-evict"
 )
 
@@ -114,7 +115,7 @@ func NewRegistryReconcilerFactory(lister operatorlister.OperatorLister, opClient
 	}
 }
 
-func Pod(source *operatorsv1alpha1.CatalogSource, name, opmImg, utilImage, img string, serviceAccount *corev1.ServiceAccount, labels, annotations map[string]string, readinessDelay, livenessDelay int32, runAsUser int64) (*corev1.Pod, error) {
+func Pod(source *operatorsv1alpha1.CatalogSource, name, opmImg, utilImage, img string, serviceAccount *corev1.ServiceAccount, labels, annotations map[string]string, readinessDelay, livenessDelay int32, runAsUser int64, defaultSecurityConfig operatorsv1alpha1.SecurityConfig) (*corev1.Pod, error) {
 	// make a copy of the labels and annotations to avoid mutating the input parameters
 	podLabels := make(map[string]string)
 	podAnnotations := make(map[string]string)
@@ -190,7 +191,7 @@ func Pod(source *operatorsv1alpha1.CatalogSource, name, opmImg, utilImage, img s
 						},
 					},
 					SecurityContext: &corev1.SecurityContext{
-						ReadOnlyRootFilesystem: ptr.To(bool(false)),
+						ReadOnlyRootFilesystem: ptr.To(false),
 					},
 					ImagePullPolicy:          image.InferImagePullPolicy(img),
 					TerminationMessagePolicy: corev1.TerminationMessageFallbackToLogsOnError,
@@ -200,13 +201,26 @@ func Pod(source *operatorsv1alpha1.CatalogSource, name, opmImg, utilImage, img s
 				"kubernetes.io/os": "linux",
 			},
 			ServiceAccountName: saName,
-			// If this field is not set, there that the is a chance that pod will be created without the imagePullSecret
+			// If this field is not set, there is a chance that pod will be created without the imagePullSecret
 			// defined by the serviceAccount
 			ImagePullSecrets: saImagePullSecrets,
 		},
 	}
 
-	if source.Spec.GrpcPodConfig != nil && source.Spec.GrpcPodConfig.SecurityContextConfig == operatorsv1alpha1.Restricted {
+	// Determine the security context configuration
+	var securityContextConfig operatorsv1alpha1.SecurityConfig
+
+	// Use the user-provided security context config if it is defined
+	if source.Spec.GrpcPodConfig != nil && source.Spec.GrpcPodConfig.SecurityContextConfig != "" {
+		securityContextConfig = source.Spec.GrpcPodConfig.SecurityContextConfig
+	} else {
+		// Default to the defaultNamespace based and provided security context config
+		securityContextConfig = defaultSecurityConfig
+	}
+
+	// Apply the appropriate security context configuration
+	if securityContextConfig == operatorsv1alpha1.Restricted {
+		// Apply 'restricted' security settings
 		addSecurityContext(pod, runAsUser)
 	}
 
@@ -332,7 +346,7 @@ func Pod(source *operatorsv1alpha1.CatalogSource, name, opmImg, utilImage, img s
 }
 
 func addSecurityContext(pod *corev1.Pod, runAsUser int64) {
-	pod.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation = ptr.To(bool(false))
+	pod.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation = ptr.To(false)
 	pod.Spec.Containers[0].SecurityContext.Capabilities = &corev1.Capabilities{
 		Drop: []corev1.Capability{"ALL"},
 	}
@@ -343,6 +357,22 @@ func addSecurityContext(pod *corev1.Pod, runAsUser int64) {
 	}
 	if runAsUser > 0 {
 		pod.Spec.SecurityContext.RunAsUser = &runAsUser
-		pod.Spec.SecurityContext.RunAsNonRoot = ptr.To(bool(true))
+		pod.Spec.SecurityContext.RunAsNonRoot = ptr.To(true)
 	}
 }
+
+// getDefaultPodContextConfig returns Restricted if the defaultNamespace has the 'pod-security.kubernetes.io/enforce' label	set to 'restricted',
+// otherwise it returns Legacy. This is used to help determine the security context of the registry pod when it is not already defined by the user
+func getDefaultPodContextConfig(client operatorclient.ClientInterface, namespace string) (operatorsv1alpha1.SecurityConfig, error) {
+	ns, err := client.KubernetesInterface().CoreV1().Namespaces().Get(context.TODO(), namespace, metav1.GetOptions{})
+	if err != nil {
+		return "", fmt.Errorf("error fetching defaultNamespace: %v", err)
+	}
+	// 'pod-security.kubernetes.io/enforce' is the label used for enforcing defaultNamespace level security,
+	// and 'restricted' is the value indicating a restricted security policy.
+	if val, exists := ns.Labels["pod-security.kubernetes.io/enforce"]; exists && val == "restricted" {
+		return operatorsv1alpha1.Restricted, nil
+	}
+
+	return operatorsv1alpha1.Legacy, nil
+}


Test patch:
diff --git a/pkg/controller/operators/catalog/operator_test.go b/pkg/controller/operators/catalog/operator_test.go
index 27535f5c4..e95458bca 100644
--- a/pkg/controller/operators/catalog/operator_test.go
+++ b/pkg/controller/operators/catalog/operator_test.go
@@ -13,6 +13,10 @@ import (
 	"testing/quick"
 	"time"
 
+	"k8s.io/utils/ptr"
+
+	controllerclient "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/controller-runtime/client"
+
 	"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install"
 
 	"github.com/sirupsen/logrus"
@@ -59,7 +63,6 @@ import (
 	"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/solver"
 	"github.com/operator-framework/operator-lifecycle-manager/pkg/fakes"
 	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/clientfake"
-	controllerclient "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/controller-runtime/client"
 	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
 	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister"
 	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil"
@@ -838,6 +841,160 @@ func withStatus(catalogSource v1alpha1.CatalogSource, status v1alpha1.CatalogSou
 	return copy
 }
 
+func TestSyncCatalogSourcesSecurityPolicy(t *testing.T) {
+	assertLegacySecurityPolicy := func(t *testing.T, pod *corev1.Pod) {
+		require.Nil(t, pod.Spec.SecurityContext)
+		require.Equal(t, &corev1.SecurityContext{
+			ReadOnlyRootFilesystem: ptr.To(false),
+		}, pod.Spec.Containers[0].SecurityContext)
+	}
+
+	assertRestrictedPolicy := func(t *testing.T, pod *corev1.Pod) {
+		require.Equal(t, &corev1.PodSecurityContext{
+			SeccompProfile: &corev1.SeccompProfile{Type: corev1.SeccompProfileTypeRuntimeDefault},
+			RunAsNonRoot:   ptr.To(true),
+			RunAsUser:      ptr.To(int64(1001)),
+		}, pod.Spec.SecurityContext)
+		require.Equal(t, &corev1.SecurityContext{
+			ReadOnlyRootFilesystem:   ptr.To(false),
+			AllowPrivilegeEscalation: ptr.To(false),
+			Capabilities: &corev1.Capabilities{
+				Drop: []corev1.Capability{"ALL"},
+			},
+		}, pod.Spec.Containers[0].SecurityContext)
+	}
+
+	clockFake := utilclocktesting.NewFakeClock(time.Date(2018, time.January, 26, 20, 40, 0, 0, time.UTC))
+	tests := []struct {
+		testName      string
+		namespace     *corev1.Namespace
+		catalogSource *v1alpha1.CatalogSource
+		check         func(*testing.T, *corev1.Pod)
+	}{
+		{
+			testName: "UnlabeledNamespace/NoUserPreference/LegacySecurityPolicy",
+			namespace: &corev1.Namespace{
+				ObjectMeta: metav1.ObjectMeta{
+					Name: "cool-namespace",
+				},
+			},
+			catalogSource: &v1alpha1.CatalogSource{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "cool-catalog",
+					Namespace: "cool-namespace",
+					UID:       types.UID("catalog-uid"),
+				},
+				Spec: v1alpha1.CatalogSourceSpec{
+					Image:      "catalog-image",
+					SourceType: v1alpha1.SourceTypeGrpc,
+				},
+			},
+			check: assertLegacySecurityPolicy,
+		}, {
+			testName: "UnlabeledNamespace/UserPreferenceForRestricted/RestrictedSecurityPolicy",
+			namespace: &corev1.Namespace{
+				ObjectMeta: metav1.ObjectMeta{
+					Name: "cool-namespace",
+				},
+			},
+			catalogSource: &v1alpha1.CatalogSource{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "cool-catalog",
+					Namespace: "cool-namespace",
+					UID:       types.UID("catalog-uid"),
+				},
+				Spec: v1alpha1.CatalogSourceSpec{
+					Image:      "catalog-image",
+					SourceType: v1alpha1.SourceTypeGrpc,
+					GrpcPodConfig: &v1alpha1.GrpcPodConfig{
+						SecurityContextConfig: v1alpha1.Restricted,
+					},
+				},
+			},
+			check: assertRestrictedPolicy,
+		}, {
+			testName: "LabeledNamespace/NoUserPreference/RestrictedSecurityPolicy",
+			namespace: &corev1.Namespace{
+				ObjectMeta: metav1.ObjectMeta{
+					Name: "cool-namespace",
+					Labels: map[string]string{
+						// restricted is the default psa policy
+						"pod-security.kubernetes.io/enforce": "restricted",
+					},
+				},
+			},
+			catalogSource: &v1alpha1.CatalogSource{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "cool-catalog",
+					Namespace: "cool-namespace",
+					UID:       types.UID("catalog-uid"),
+				},
+				Spec: v1alpha1.CatalogSourceSpec{
+					Image:      "catalog-image",
+					SourceType: v1alpha1.SourceTypeGrpc,
+				},
+			},
+			check: assertRestrictedPolicy,
+		}, {
+			testName: "LabeledNamespace/UserPreferenceForLegacy/LegacySecurityPolicy",
+			namespace: &corev1.Namespace{
+				ObjectMeta: metav1.ObjectMeta{
+					Name: "cool-namespace",
+				},
+			},
+			catalogSource: &v1alpha1.CatalogSource{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "cool-catalog",
+					Namespace: "cool-namespace",
+					UID:       types.UID("catalog-uid"),
+				},
+				Spec: v1alpha1.CatalogSourceSpec{
+					Image:      "catalog-image",
+					SourceType: v1alpha1.SourceTypeGrpc,
+					GrpcPodConfig: &v1alpha1.GrpcPodConfig{
+						SecurityContextConfig: v1alpha1.Legacy,
+					},
+				},
+			},
+			check: assertLegacySecurityPolicy,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.testName, func(t *testing.T) {
+			// Create existing objects
+			clientObjs := []runtime.Object{tt.catalogSource}
+
+			// Create test operator
+			ctx, cancel := context.WithCancel(context.TODO())
+			defer cancel()
+
+			op, err := NewFakeOperator(
+				ctx,
+				tt.namespace.GetName(),
+				[]string{tt.namespace.GetName()},
+				withClock(clockFake),
+				withClientObjs(clientObjs...),
+			)
+			require.NoError(t, err)
+
+			// Because NewFakeOperator creates the namespace, we need to update the namespace to match the test case
+			// before running the sync function
+			_, err = op.opClient.KubernetesInterface().CoreV1().Namespaces().Update(context.TODO(), tt.namespace, metav1.UpdateOptions{})
+			require.NoError(t, err)
+
+			// Run sync
+			err = op.syncCatalogSources(tt.catalogSource)
+			require.NoError(t, err)
+
+			pods, err := op.opClient.KubernetesInterface().CoreV1().Pods(tt.catalogSource.Namespace).List(context.TODO(), metav1.ListOptions{})
+			require.NoError(t, err)
+			require.Len(t, pods.Items, 1)
+
+			tt.check(t, &pods.Items[0])
+		})
+	}
+}
+
 func TestSyncCatalogSources(t *testing.T) {
 	clockFake := utilclocktesting.NewFakeClock(time.Date(2018, time.January, 26, 20, 40, 0, 0, time.UTC))
 	now := metav1.NewTime(clockFake.Now())
@@ -1165,7 +1322,7 @@ func TestSyncCatalogSources(t *testing.T) {
 			if tt.expectedStatus != nil {
 				if tt.expectedStatus.GRPCConnectionState != nil {
 					updated.Status.GRPCConnectionState.LastConnectTime = now
-					// Ignore LastObservedState difference if an expected LastObservedState is no provided
+					// Ignore LastObservedState difference if an expected LastObservedState is not provided
 					if tt.expectedStatus.GRPCConnectionState.LastObservedState == "" {
 						updated.Status.GRPCConnectionState.LastObservedState = ""
 					}
@@ -2012,7 +2169,6 @@ func NewFakeOperator(ctx context.Context, namespace string, namespaces []string,
 			return nil, err
 		}
 		applier := controllerclient.NewFakeApplier(s, "testowner")
-
 		op.reconciler = reconciler.NewRegistryReconcilerFactory(lister, op.opClient, "test:pod", op.now, applier, 1001, "", "")
 	}
 
@@ -2028,7 +2184,6 @@ func NewFakeOperator(ctx context.Context, namespace string, namespaces []string,
 
 	return op, nil
 }
-
 func installPlan(name, namespace string, phase v1alpha1.InstallPlanPhase, names ...string) *v1alpha1.InstallPlan {
 	return &v1alpha1.InstallPlan{
 		ObjectMeta: metav1.ObjectMeta{
@@ -2175,7 +2330,7 @@ func pod(t *testing.T, s v1alpha1.CatalogSource) *corev1.Pod {
 			Name:      s.GetName(),
 		},
 	}
-	pod, err := reconciler.Pod(&s, "registry-server", "central-opm", "central-util", s.Spec.Image, serviceAccount, s.GetLabels(), s.GetAnnotations(), 5, 10, 1001)
+	pod, err := reconciler.Pod(&s, "registry-server", "central-opm", "central-util", s.Spec.Image, serviceAccount, s.GetLabels(), s.GetAnnotations(), 5, 10, 1001, v1alpha1.Legacy)
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/pkg/controller/registry/reconciler/configmap_test.go b/pkg/controller/registry/reconciler/configmap_test.go
index 7e6b1dcd7..9635a5b59 100644
--- a/pkg/controller/registry/reconciler/configmap_test.go
+++ b/pkg/controller/registry/reconciler/configmap_test.go
@@ -186,7 +186,12 @@ func validConfigMapCatalogSource(configMap *corev1.ConfigMap) *v1alpha1.CatalogS
 }
 
 func objectsForCatalogSource(t *testing.T, catsrc *v1alpha1.CatalogSource) []runtime.Object {
-	var objs []runtime.Object
+	// the registry pod security context is derived from the defaultNamespace by default
+	// therefore a namespace resource must always be present
+	var objs = []runtime.Object{
+		defaultNamespace(),
+	}
+
 	switch catsrc.Spec.SourceType {
 	case v1alpha1.SourceTypeInternal, v1alpha1.SourceTypeConfigmap:
 		decorated := configMapCatalogSourceDecorator{catsrc, runAsUser}
@@ -194,16 +199,15 @@ func objectsForCatalogSource(t *testing.T, catsrc *v1alpha1.CatalogSource) []run
 		if err != nil {
 			t.Fatal(err)
 		}
-		pod, err := decorated.Pod(registryImageName)
+		serviceAccount := decorated.ServiceAccount()
+		pod, err := decorated.Pod(registryImageName, defaultPodSecurityConfig)
 		if err != nil {
 			t.Fatal(err)
 		}
-		objs = clientfake.AddSimpleGeneratedNames(
-			clientfake.AddSimpleGeneratedName(pod),
+		objs = append(objs,
+			pod,
 			service,
-			decorated.ServiceAccount(),
-			decorated.Role(),
-			decorated.RoleBinding(),
+			serviceAccount,
 		)
 	case v1alpha1.SourceTypeGrpc:
 		if catsrc.Spec.Image != "" {
@@ -213,11 +217,11 @@ func objectsForCatalogSource(t *testing.T, catsrc *v1alpha1.CatalogSource) []run
 			if err != nil {
 				t.Fatal(err)
 			}
-			pod, err := decorated.Pod(serviceAccount)
+			pod, err := decorated.Pod(serviceAccount, defaultPodSecurityConfig)
 			if err != nil {
 				t.Fatal(err)
 			}
-			objs = clientfake.AddSimpleGeneratedNames(
+			objs = append(objs,
 				pod,
 				service,
 				serviceAccount,
@@ -242,7 +246,7 @@ func objectsForCatalogSource(t *testing.T, catsrc *v1alpha1.CatalogSource) []run
 }
 
 func modifyObjName(objs []runtime.Object, kind runtime.Object, newName string) []runtime.Object {
-	out := []runtime.Object{}
+	var out []runtime.Object
 	t := reflect.TypeOf(kind)
 	for _, obj := range objs {
 		o := obj.DeepCopyObject()
@@ -257,7 +261,7 @@ func modifyObjName(objs []runtime.Object, kind runtime.Object, newName string) [
 }
 
 func setLabel(objs []runtime.Object, kind runtime.Object, label, value string) []runtime.Object {
-	out := []runtime.Object{}
+	var out []runtime.Object
 	t := reflect.TypeOf(kind)
 	for _, obj := range objs {
 		o := obj.DeepCopyObject()
@@ -297,10 +301,15 @@ func TestConfigMapRegistryReconciler(t *testing.T) {
 		{
 			testName: "NoConfigMap",
 			in: in{
-				cluster: cluster{},
+				cluster: cluster{
+					k8sObjs: []runtime.Object{
+						validConfigMap,
+						defaultNamespace(),
+					},
+				},
 				catsrc: &v1alpha1.CatalogSource{
 					ObjectMeta: metav1.ObjectMeta{
-						Namespace: "test-ns",
+						Namespace: testNamespace,
 					},
 					Spec: v1alpha1.CatalogSourceSpec{
 						SourceType: v1alpha1.SourceTypeConfigmap,
@@ -309,14 +318,17 @@ func TestConfigMapRegistryReconciler(t *testing.T) {
 				},
 			},
 			out: out{
-				err: fmt.Errorf(`unable to find configmap test-ns/test-cm: configmaps "test-cm" not found`),
+				err: fmt.Errorf(`unable to find configmap testns/test-cm: configmaps "test-cm" not found`),
 			},
 		},
 		{
 			testName: "NoExistingRegistry/CreateSuccessful",
 			in: in{
 				cluster: cluster{
-					k8sObjs: []runtime.Object{validConfigMap},
+					k8sObjs: []runtime.Object{
+						validConfigMap,
+						defaultNamespace(),
+					},
 				},
 				catsrc: validCatalogSource,
 			},
@@ -481,7 +493,7 @@ func TestConfigMapRegistryReconciler(t *testing.T) {
 			// if no error, the reconciler should create the same set of kube objects every time
 			decorated := configMapCatalogSourceDecorator{tt.in.catsrc, runAsUser}
 
-			pod, err := decorated.Pod(registryImageName)
+			pod, err := decorated.Pod(registryImageName, defaultPodSecurityConfig)
 			require.NoError(t, err)
 			listOptions := metav1.ListOptions{LabelSelector: labels.SelectorFromSet(labels.Set{CatalogSourceLabelKey: tt.in.catsrc.GetName()}).String()}
 			outPods, err := client.KubernetesInterface().CoreV1().Pods(pod.GetNamespace()).List(context.TODO(), listOptions)
diff --git a/pkg/controller/registry/reconciler/grpc_test.go b/pkg/controller/registry/reconciler/grpc_test.go
index fd505fcf6..65071feda 100644
--- a/pkg/controller/registry/reconciler/grpc_test.go
+++ b/pkg/controller/registry/reconciler/grpc_test.go
@@ -2,11 +2,9 @@ package reconciler
 
 import (
 	"context"
-	"fmt"
 	"testing"
 	"time"
 
-	"github.com/google/go-cmp/cmp"
 	"github.com/operator-framework/api/pkg/operators/v1alpha1"
 	"github.com/sirupsen/logrus"
 	"github.com/stretchr/testify/require"
@@ -26,7 +24,7 @@ func validGrpcCatalogSource(image, address string) *v1alpha1.CatalogSource {
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      "img-catalog",
 			Namespace: testNamespace,
-			UID:       types.UID("catalog-uid"),
+			UID:       "catalog-uid",
 			Labels:    map[string]string{"olm.catalogSource": "img-catalog"},
 		},
 		Spec: v1alpha1.CatalogSourceSpec{
@@ -101,6 +99,9 @@ func TestGrpcRegistryReconciler(t *testing.T) {
 		{
 			testName: "Grpc/NoExistingRegistry/CreateSuccessful",
 			in: in{
+				cluster: cluster{
+					k8sObjs: baseClusterState(),
+				},
 				catsrc: validGrpcCatalogSource("test-img", ""),
 			},
 			out: out{
@@ -116,6 +117,9 @@ func TestGrpcRegistryReconciler(t *testing.T) {
 		{
 			testName: "Grpc/NoExistingRegistry/CreateSuccessful/CatalogSourceWithPeriodInNameCreatesValidServiceName",
 			in: in{
+				cluster: cluster{
+					k8sObjs: baseClusterState(),
+				},
 				catsrc: grpcCatalogSourceWithName("img.catalog"),
 			},
 			out: out{
@@ -149,8 +153,10 @@ func TestGrpcRegistryReconciler(t *testing.T) {
 		{
 			testName: "Grpc/Address/CreateSuccessful",
 			in: in{
-				cluster: cluster{},
-				catsrc:  validGrpcCatalogSource("", "catalog.svc.cluster.local:50001"),
+				cluster: cluster{
+					k8sObjs: baseClusterState(),
+				},
+				catsrc: validGrpcCatalogSource("", "catalog.svc.cluster.local:50001"),
 			},
 			out: out{
 				status: &v1alpha1.RegistryServiceStatus{
@@ -162,8 +168,10 @@ func TestGrpcRegistryReconciler(t *testing.T) {
 		{
 			testName: "Grpc/AddressAndImage/CreateSuccessful",
 			in: in{
-				cluster: cluster{},
-				catsrc:  validGrpcCatalogSource("img-catalog", "catalog.svc.cluster.local:50001"),
+				cluster: cluster{
+					k8sObjs: baseClusterState(),
+				},
+				catsrc: validGrpcCatalogSource("img-catalog", "catalog.svc.cluster.local:50001"),
 			},
 			out: out{
 				status: &v1alpha1.RegistryServiceStatus{
@@ -252,6 +260,7 @@ func TestGrpcRegistryReconciler(t *testing.T) {
 			in: in{
 				cluster: cluster{
 					k8sObjs: []runtime.Object{
+						defaultNamespace(),
 						&corev1.Secret{
 							ObjectMeta: metav1.ObjectMeta{
 								Name:      "test-secret",
@@ -301,6 +310,9 @@ func TestGrpcRegistryReconciler(t *testing.T) {
 		{
 			testName: "Grpc/NoExistingRegistry/CreateWithAnnotations",
 			in: in{
+				cluster: cluster{
+					k8sObjs: baseClusterState(),
+				},
 				catsrc: grpcCatalogSourceWithAnnotations(map[string]string{
 					"annotation1": "value1",
 					"annotation2": "value2",
@@ -360,7 +372,7 @@ func TestGrpcRegistryReconciler(t *testing.T) {
 			// Check for resource existence
 			decorated := grpcCatalogSourceDecorator{CatalogSource: tt.in.catsrc, createPodAsUser: runAsUser}
 			sa := decorated.ServiceAccount()
-			pod, err := decorated.Pod(sa)
+			pod, err := decorated.Pod(sa, defaultPodSecurityConfig)
 			if err != nil {
 				t.Fatal(err)
 			}
@@ -376,9 +388,6 @@ func TestGrpcRegistryReconciler(t *testing.T) {
 			case *GrpcRegistryReconciler:
 				// Should be created by a GrpcRegistryReconciler
 				require.NoError(t, podErr)
-				if diff := cmp.Diff(outPods.Items, []corev1.Pod{*pod}); diff != "" {
-					fmt.Printf("incorrect pods: %s\n", diff)
-				}
 				require.Len(t, outPods.Items, 1)
 				outPod := outPods.Items[0]
 				require.Equal(t, pod.GetGenerateName(), outPod.GetGenerateName())
@@ -450,7 +459,11 @@ func TestRegistryPodPriorityClass(t *testing.T) {
 			stopc := make(chan struct{})
 			defer close(stopc)
 
-			factory, client := fakeReconcilerFactory(t, stopc, withNow(now), withK8sObjs(tt.in.cluster.k8sObjs...), withK8sClientOptions(clientfake.WithNameGeneration(t)))
+			// a defaultNamespace resource must be present so that the reconciler can determine the
+			// security context configuration for the underlying pod
+			clusterState := append(tt.in.cluster.k8sObjs, defaultNamespace())
+
+			factory, client := fakeReconcilerFactory(t, stopc, withNow(now), withK8sObjs(clusterState...), withK8sClientOptions(clientfake.WithNameGeneration(t)))
 			rec := factory.ReconcilerForSource(tt.in.catsrc)
 
 			err := rec.EnsureRegistryServer(logrus.NewEntry(logrus.New()), tt.in.catsrc)
@@ -458,7 +471,7 @@ func TestRegistryPodPriorityClass(t *testing.T) {
 
 			// Check for resource existence
 			decorated := grpcCatalogSourceDecorator{CatalogSource: tt.in.catsrc, createPodAsUser: runAsUser}
-			pod, err := decorated.Pod(serviceAccount(tt.in.catsrc.Namespace, tt.in.catsrc.Name))
+			pod, err := decorated.Pod(serviceAccount(tt.in.catsrc.Namespace, tt.in.catsrc.Name), defaultPodSecurityConfig)
 			require.NoError(t, err)
 			listOptions := metav1.ListOptions{LabelSelector: labels.SelectorFromSet(labels.Set{CatalogSourceLabelKey: tt.in.catsrc.GetName()}).String()}
 			outPods, podErr := client.KubernetesInterface().CoreV1().Pods(pod.GetNamespace()).List(context.TODO(), listOptions)
@@ -581,8 +594,7 @@ func TestGrpcRegistryChecker(t *testing.T) {
 		{
 			testName: "Grpc/NoExistingRegistry/AddressAndImage/NotHealthy",
 			in: in{
-				cluster: cluster{},
-				catsrc:  validGrpcCatalogSource("img-catalog", "catalog.svc.cluster.local:50001"),
+				catsrc: validGrpcCatalogSource("img-catalog", "catalog.svc.cluster.local:50001"),
 			},
 			out: out{
 				healthy: false,
diff --git a/pkg/controller/registry/reconciler/reconciler_test.go b/pkg/controller/registry/reconciler/reconciler_test.go
index f86aac77f..976d92a9d 100644
--- a/pkg/controller/registry/reconciler/reconciler_test.go
+++ b/pkg/controller/registry/reconciler/reconciler_test.go
@@ -3,6 +3,8 @@ package reconciler
 import (
 	"testing"
 
+	"k8s.io/apimachinery/pkg/runtime"
+
 	"github.com/google/go-cmp/cmp"
 	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/image"
 	"github.com/stretchr/testify/require"
@@ -15,6 +17,7 @@ import (
 )
 
 const workloadUserID = 1001
+const defaultPodSecurityConfig = v1alpha1.Restricted
 
 func TestPodMemoryTarget(t *testing.T) {
 	q := resource.MustParse("5Mi")
@@ -79,7 +82,7 @@ func TestPodMemoryTarget(t *testing.T) {
 								},
 							},
 							SecurityContext: &corev1.SecurityContext{
-								ReadOnlyRootFilesystem: ptr.To(bool(false)),
+								ReadOnlyRootFilesystem: ptr.To(false),
 							},
 							ImagePullPolicy:          image.InferImagePullPolicy("image"),
 							TerminationMessagePolicy: "FallbackToLogsOnError",
@@ -153,7 +156,7 @@ func TestPodMemoryTarget(t *testing.T) {
 								Limits: corev1.ResourceList{},
 							},
 							SecurityContext: &corev1.SecurityContext{
-								ReadOnlyRootFilesystem: ptr.To(bool(false)),
+								ReadOnlyRootFilesystem: ptr.To(false),
 							},
 							ImagePullPolicy:          image.InferImagePullPolicy("image"),
 							TerminationMessagePolicy: "FallbackToLogsOnError",
@@ -167,11 +170,13 @@ func TestPodMemoryTarget(t *testing.T) {
 	}
 
 	for _, testCase := range testCases {
-		pod, err := Pod(testCase.input, "name", "opmImage", "utilImage", "image", serviceAccount("", "service-account"), map[string]string{}, map[string]string{}, int32(0), int32(0), int64(workloadUserID))
-		require.NoError(t, err)
-		if diff := cmp.Diff(pod, testCase.expected); diff != "" {
-			t.Errorf("got incorrect pod: %v", diff)
-		}
+		t.Run(testCase.name, func(t *testing.T) {
+			pod, err := Pod(testCase.input, "name", "opmImage", "utilImage", "image", serviceAccount("", "service-account"), map[string]string{}, map[string]string{}, int32(0), int32(0), int64(workloadUserID), v1alpha1.Legacy)
+			require.NoError(t, err)
+			if diff := cmp.Diff(pod, testCase.expected); diff != "" {
+				t.Errorf("got incorrect pod: %v", diff)
+			}
+		})
 	}
 }
 
@@ -246,7 +251,7 @@ func TestPodExtractContent(t *testing.T) {
 								},
 							},
 							SecurityContext: &corev1.SecurityContext{
-								ReadOnlyRootFilesystem: ptr.To(bool(false)),
+								ReadOnlyRootFilesystem: ptr.To(false),
 							},
 							ImagePullPolicy:          image.InferImagePullPolicy("image"),
 							TerminationMessagePolicy: "FallbackToLogsOnError",
@@ -360,7 +365,7 @@ func TestPodExtractContent(t *testing.T) {
 								},
 							},
 							SecurityContext: &corev1.SecurityContext{
-								ReadOnlyRootFilesystem: ptr.To(bool(false)),
+								ReadOnlyRootFilesystem: ptr.To(false),
 							},
 							ImagePullPolicy:          image.InferImagePullPolicy("image"),
 							TerminationMessagePolicy: "FallbackToLogsOnError",
@@ -375,7 +380,7 @@ func TestPodExtractContent(t *testing.T) {
 	}
 
 	for _, testCase := range testCases {
-		pod, err := Pod(testCase.input, "name", "opmImage", "utilImage", "image", serviceAccount("", "service-account"), map[string]string{}, map[string]string{}, int32(0), int32(0), int64(workloadUserID))
+		pod, err := Pod(testCase.input, "name", "opmImage", "utilImage", "image", serviceAccount("", "service-account"), map[string]string{}, map[string]string{}, int32(0), int32(0), int64(workloadUserID), v1alpha1.Legacy)
 		require.NoError(t, err)
 		if diff := cmp.Diff(pod, testCase.expected); diff != "" {
 			t.Errorf("got incorrect pod: %v", diff)
@@ -426,7 +431,7 @@ func TestPodServiceAccountImagePullSecrets(t *testing.T) {
 	}
 
 	for _, testCase := range testCases {
-		pod, err := Pod(catalogSource, "name", "opmImage", "utilImage", "image", testCase.serviceAccount, map[string]string{}, map[string]string{}, int32(0), int32(0), int64(workloadUserID))
+		pod, err := Pod(catalogSource, "name", "opmImage", "utilImage", "image", testCase.serviceAccount, map[string]string{}, map[string]string{}, int32(0), int32(0), int64(workloadUserID), v1alpha1.Legacy)
 		require.NoError(t, err)
 		if diff := cmp.Diff(testCase.serviceAccount.ImagePullSecrets, pod.Spec.ImagePullSecrets); diff != "" {
 			t.Errorf("got incorrect pod: %v", diff)
@@ -445,7 +450,7 @@ func TestPodNodeSelector(t *testing.T) {
 	key := "kubernetes.io/os"
 	value := "linux"
 
-	gotCatSrcPod, err := Pod(catsrc, "hello", "utilImage", "opmImage", "busybox", serviceAccount("", "service-account"), map[string]string{}, map[string]string{}, int32(0), int32(0), int64(workloadUserID))
+	gotCatSrcPod, err := Pod(catsrc, "hello", "utilImage", "opmImage", "busybox", serviceAccount("", "service-account"), map[string]string{}, map[string]string{}, int32(0), int32(0), int64(workloadUserID), v1alpha1.Legacy)
 	require.NoError(t, err)
 	gotCatSrcPodSelector := gotCatSrcPod.Spec.NodeSelector
 
@@ -494,7 +499,7 @@ func TestPullPolicy(t *testing.T) {
 	}
 
 	for _, tt := range table {
-		p, err := Pod(source, "catalog", "opmImage", "utilImage", tt.image, serviceAccount("", "service-account"), nil, nil, int32(0), int32(0), int64(workloadUserID))
+		p, err := Pod(source, "catalog", "opmImage", "utilImage", tt.image, serviceAccount("", "service-account"), nil, nil, int32(0), int32(0), int64(workloadUserID), v1alpha1.Legacy)
 		require.NoError(t, err)
 		policy := p.Spec.Containers[0].ImagePullPolicy
 		if policy != tt.policy {
@@ -507,52 +512,88 @@ func TestPodContainerSecurityContext(t *testing.T) {
 	testcases := []struct {
 		title                            string
 		inputCatsrc                      *v1alpha1.CatalogSource
+		namespacePodSecurityConfig       v1alpha1.SecurityConfig
 		expectedSecurityContext          *corev1.PodSecurityContext
 		expectedContainerSecurityContext *corev1.SecurityContext
 	}{
 		{
-			title: "NoSpecDefined/PodContainsSecurityConfigForPSALegacy",
+			title: "NoSpecDefined/NamespaceRestricted/UseRestricted",
 			inputCatsrc: &v1alpha1.CatalogSource{
 				ObjectMeta: metav1.ObjectMeta{
 					Name:      "test",
-					Namespace: "testns",
+					Namespace: testNamespace,
 				},
 			},
-			expectedContainerSecurityContext: nil,
+			namespacePodSecurityConfig: v1alpha1.Restricted,
+			expectedContainerSecurityContext: &corev1.SecurityContext{
+				AllowPrivilegeEscalation: ptr.To(false),
+				Capabilities: &corev1.Capabilities{
+					Drop: []corev1.Capability{"ALL"},
+				},
+				ReadOnlyRootFilesystem: ptr.To(false), // Reflecting expected 'restricted' settings
+			},
+			expectedSecurityContext: &corev1.PodSecurityContext{
+				SeccompProfile: &corev1.SeccompProfile{Type: corev1.SeccompProfileTypeRuntimeDefault},
+				RunAsNonRoot:   ptr.To(true),
+				RunAsUser:      ptr.To(int64(workloadUserID)),
+			},
+		},
+		{
+			title:                      "NoSpecDefined/NamespaceNotRestricted/UseLegacy",
+			namespacePodSecurityConfig: v1alpha1.Legacy,
+			inputCatsrc: &v1alpha1.CatalogSource{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "test",
+					Namespace: testNamespace,
+				},
+			},
+			expectedContainerSecurityContext: &corev1.SecurityContext{ReadOnlyRootFilesystem: ptr.To(false)},
 			expectedSecurityContext:          nil,
 		},
 		{
-			title: "SpecDefined/NoGRPCPodConfig/PodContainsSecurityConfigForPSALegacy",
+			title: "SpecDefined/NoGRPCPodConfig/NamespaceRestricted/UseRestricted",
 			inputCatsrc: &v1alpha1.CatalogSource{
 				ObjectMeta: metav1.ObjectMeta{
 					Name:      "test",
-					Namespace: "testns",
+					Namespace: testNamespace,
 				},
 				Spec: v1alpha1.CatalogSourceSpec{},
 			},
-			expectedContainerSecurityContext: nil,
-			expectedSecurityContext:          nil,
+			namespacePodSecurityConfig: v1alpha1.Restricted,
+			expectedContainerSecurityContext: &corev1.SecurityContext{
+				AllowPrivilegeEscalation: ptr.To(false),
+				Capabilities: &corev1.Capabilities{
+					Drop: []corev1.Capability{"ALL"},
+				},
+				ReadOnlyRootFilesystem: ptr.To(false),
+			},
+			expectedSecurityContext: &corev1.PodSecurityContext{
+				SeccompProfile: &corev1.SeccompProfile{Type: corev1.SeccompProfileTypeRuntimeDefault},
+				RunAsNonRoot:   ptr.To(true),
+				RunAsUser:      ptr.To(int64(workloadUserID)),
+			},
 		},
 		{
-			title: "SpecDefined/GRPCPodConfigDefined/PodContainsSecurityConfigForPSALegacy",
+			title: "SpecDefined/NoGRPCPodConfig/NamespaceNotRestricted/UseLegacy",
 			inputCatsrc: &v1alpha1.CatalogSource{
 				ObjectMeta: metav1.ObjectMeta{
 					Name:      "test",
-					Namespace: "testns",
+					Namespace: testNamespace,
 				},
 				Spec: v1alpha1.CatalogSourceSpec{
 					GrpcPodConfig: &v1alpha1.GrpcPodConfig{},
 				},
 			},
-			expectedContainerSecurityContext: nil,
+			namespacePodSecurityConfig:       v1alpha1.Legacy,
+			expectedContainerSecurityContext: &corev1.SecurityContext{ReadOnlyRootFilesystem: ptr.To(false)},
 			expectedSecurityContext:          nil,
 		},
 		{
-			title: "SpecDefined/SecurityContextConfig:Legacy/PodContainsSecurityConfigForPSALegacy",
+			title: "SpecDefined/SecurityContextConfig:Legacy/NoChangeExpected",
 			inputCatsrc: &v1alpha1.CatalogSource{
 				ObjectMeta: metav1.ObjectMeta{
 					Name:      "test",
-					Namespace: "testns",
+					Namespace: testNamespace,
 				},
 				Spec: v1alpha1.CatalogSourceSpec{
 					GrpcPodConfig: &v1alpha1.GrpcPodConfig{
@@ -560,15 +601,16 @@ func TestPodContainerSecurityContext(t *testing.T) {
 					},
 				},
 			},
-			expectedContainerSecurityContext: nil,
+			namespacePodSecurityConfig:       v1alpha1.Restricted, // set to the opposite of the config to catch possible errors
+			expectedContainerSecurityContext: &corev1.SecurityContext{ReadOnlyRootFilesystem: ptr.To(false)},
 			expectedSecurityContext:          nil,
 		},
 		{
-			title: "SpecDefined/SecurityContextConfig:Restricted/PodContainsSecurityConfigForPSARestricted",
+			title: "SpecDefined/SecurityContextConfig:Restricted/RestrictedSecurityConfigApplied",
 			inputCatsrc: &v1alpha1.CatalogSource{
 				ObjectMeta: metav1.ObjectMeta{
 					Name:      "test",
-					Namespace: "testns",
+					Namespace: testNamespace,
 				},
 				Spec: v1alpha1.CatalogSourceSpec{
 					GrpcPodConfig: &v1alpha1.GrpcPodConfig{
@@ -576,45 +618,33 @@ func TestPodContainerSecurityContext(t *testing.T) {
 					},
 				},
 			},
+			namespacePodSecurityConfig: v1alpha1.Legacy, // set to the opposite of the config to catch possible errors
 			expectedContainerSecurityContext: &corev1.SecurityContext{
-				ReadOnlyRootFilesystem:   ptr.To(bool(false)),
-				AllowPrivilegeEscalation: ptr.To(bool(false)),
+				ReadOnlyRootFilesystem:   ptr.To(false),
+				AllowPrivilegeEscalation: ptr.To(false),
 				Capabilities: &corev1.Capabilities{
 					Drop: []corev1.Capability{"ALL"},
 				},
 			},
 			expectedSecurityContext: &corev1.PodSecurityContext{
 				SeccompProfile: &corev1.SeccompProfile{Type: corev1.SeccompProfileTypeRuntimeDefault},
+				RunAsNonRoot:   ptr.To(true),
 				RunAsUser:      ptr.To(int64(workloadUserID)),
-				RunAsNonRoot:   ptr.To(bool(true)),
-			},
-		},
-		{
-			title: "SpecDefined/SecurityContextConfig:Legacy/PodDoesNotContainsSecurityConfig",
-			inputCatsrc: &v1alpha1.CatalogSource{
-				ObjectMeta: metav1.ObjectMeta{
-					Name:      "test",
-					Namespace: "testns",
-				},
-				Spec: v1alpha1.CatalogSourceSpec{
-					GrpcPodConfig: &v1alpha1.GrpcPodConfig{
-						SecurityContextConfig: v1alpha1.Legacy,
-					},
-				},
 			},
-			expectedContainerSecurityContext: nil,
-			expectedSecurityContext:          nil,
 		},
 	}
+
 	for _, testcase := range testcases {
-		outputPod, err := Pod(testcase.inputCatsrc, "hello", "utilImage", "opmImage", "busybox", serviceAccount("", "service-account"), map[string]string{}, map[string]string{}, int32(0), int32(0), int64(workloadUserID))
-		require.NoError(t, err)
-		if testcase.expectedSecurityContext != nil {
+		t.Run(testcase.title, func(t *testing.T) {
+			outputPod, err := Pod(testcase.inputCatsrc, "hello", "utilImage", "opmImage", "busybox", serviceAccount("", "service-account"), map[string]string{}, map[string]string{}, int32(0), int32(0), workloadUserID, testcase.namespacePodSecurityConfig)
+			require.NoError(t, err)
+
+			// Assert PodSecurityContext
 			require.Equal(t, testcase.expectedSecurityContext, outputPod.Spec.SecurityContext)
-		}
-		if testcase.expectedContainerSecurityContext != nil {
+
+			// Assert ContainerSecurityContext
 			require.Equal(t, testcase.expectedContainerSecurityContext, outputPod.Spec.Containers[0].SecurityContext)
-		}
+		})
 	}
 }
 
@@ -638,7 +668,7 @@ func TestPodAvoidsConcurrentWrite(t *testing.T) {
 		"annotation": "somethingelse",
 	}
 
-	gotPod, err := Pod(catsrc, "hello", "opmImage", "utilImage", "busybox", serviceAccount("", "service-account"), labels, annotations, int32(0), int32(0), int64(workloadUserID))
+	gotPod, err := Pod(catsrc, "hello", "opmImage", "utilImage", "busybox", serviceAccount("", "service-account"), labels, annotations, int32(0), int32(0), int64(workloadUserID), v1alpha1.Legacy)
 	require.NoError(t, err)
 
 	// check labels and annotations point to different addresses between parameters and what's in the pod
@@ -868,7 +898,7 @@ func TestPodSchedulingOverrides(t *testing.T) {
 	}
 
 	for _, testCase := range testCases {
-		pod, err := Pod(testCase.catalogSource, "hello", "opmImage", "utilImage", "busybox", serviceAccount("", "service-account"), map[string]string{}, testCase.annotations, int32(0), int32(0), int64(workloadUserID))
+		pod, err := Pod(testCase.catalogSource, "hello", "opmImage", "utilImage", "busybox", serviceAccount("", "service-account"), map[string]string{}, testCase.annotations, int32(0), int32(0), int64(workloadUserID), v1alpha1.Legacy)
 		require.NoError(t, err)
 		require.Equal(t, testCase.expectedNodeSelectors, pod.Spec.NodeSelector)
 		require.Equal(t, testCase.expectedPriorityClassName, pod.Spec.PriorityClassName)
@@ -876,3 +906,26 @@ func TestPodSchedulingOverrides(t *testing.T) {
 		require.Equal(t, testCase.expectedAffinity, pod.Spec.Affinity)
 	}
 }
+
+// baseClusterState returns a list of runtime objects that are required for the tests to run including the
+// target namespace with the assumed default configuration
+func baseClusterState() []runtime.Object {
+	return []runtime.Object{
+		defaultNamespace(),
+	}
+}
+
+// defaultNamespace returns a kubernetes namespace with the assumes default settings,
+// e.g. Pod Security Admission security policy label
+func defaultNamespace() *corev1.Namespace {
+	return &corev1.Namespace{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: testNamespace,
+			Labels: map[string]string{
+				// catalogsource pod security configuration depends on the defaultNamespace psa configuration
+				// adding restricted PSA label as this is the default
+				"pod-security.kubernetes.io/enforce": "restricted",
+			},
+		},
+	}
+}
diff --git a/vendor/github.com/golang-migrate/migrate/v4/source/iofs/testdata/migrations/1_foobar.down.sql b/vendor/github.com/golang-migrate/migrate/v4/source/iofs/testdata/migrations/1_foobar.down.sql
deleted file mode 100644
index 4267951a5..000000000
--- a/vendor/github.com/golang-migrate/migrate/v4/source/iofs/testdata/migrations/1_foobar.down.sql
+++ /dev/null
@@ -1,1 +0,0 @@
-1 down
diff --git a/vendor/github.com/golang-migrate/migrate/v4/source/iofs/testdata/migrations/1_foobar.up.sql b/vendor/github.com/golang-migrate/migrate/v4/source/iofs/testdata/migrations/1_foobar.up.sql
deleted file mode 100644
index 046fd5a5d..000000000
--- a/vendor/github.com/golang-migrate/migrate/v4/source/iofs/testdata/migrations/1_foobar.up.sql
+++ /dev/null
@@ -1,1 +0,0 @@
-1 up
diff --git a/vendor/github.com/golang-migrate/migrate/v4/source/iofs/testdata/migrations/3_foobar.up.sql b/vendor/github.com/golang-migrate/migrate/v4/source/iofs/testdata/migrations/3_foobar.up.sql
deleted file mode 100644
index 77c1b77dc..000000000
--- a/vendor/github.com/golang-migrate/migrate/v4/source/iofs/testdata/migrations/3_foobar.up.sql
+++ /dev/null
@@ -1,1 +0,0 @@
-3 up
diff --git a/vendor/github.com/golang-migrate/migrate/v4/source/iofs/testdata/migrations/4_foobar.down.sql b/vendor/github.com/golang-migrate/migrate/v4/source/iofs/testdata/migrations/4_foobar.down.sql
deleted file mode 100644
index b405d8bd0..000000000
--- a/vendor/github.com/golang-migrate/migrate/v4/source/iofs/testdata/migrations/4_foobar.down.sql
+++ /dev/null
@@ -1,1 +0,0 @@
-4 down
diff --git a/vendor/github.com/golang-migrate/migrate/v4/source/iofs/testdata/migrations/4_foobar.up.sql b/vendor/github.com/golang-migrate/migrate/v4/source/iofs/testdata/migrations/4_foobar.up.sql
deleted file mode 100644
index eba61bb94..000000000
--- a/vendor/github.com/golang-migrate/migrate/v4/source/iofs/testdata/migrations/4_foobar.up.sql
+++ /dev/null
@@ -1,1 +0,0 @@
-4 up
diff --git a/vendor/github.com/golang-migrate/migrate/v4/source/iofs/testdata/migrations/5_foobar.down.sql b/vendor/github.com/golang-migrate/migrate/v4/source/iofs/testdata/migrations/5_foobar.down.sql
deleted file mode 100644
index 6dc96e206..000000000
--- a/vendor/github.com/golang-migrate/migrate/v4/source/iofs/testdata/migrations/5_foobar.down.sql
+++ /dev/null
@@ -1,1 +0,0 @@
-5 down
diff --git a/vendor/github.com/golang-migrate/migrate/v4/source/iofs/testdata/migrations/7_foobar.down.sql b/vendor/github.com/golang-migrate/migrate/v4/source/iofs/testdata/migrations/7_foobar.down.sql
deleted file mode 100644
index 46636016b..000000000
--- a/vendor/github.com/golang-migrate/migrate/v4/source/iofs/testdata/migrations/7_foobar.down.sql
+++ /dev/null
@@ -1,1 +0,0 @@
-7 down
diff --git a/vendor/github.com/golang-migrate/migrate/v4/source/iofs/testdata/migrations/7_foobar.up.sql b/vendor/github.com/golang-migrate/migrate/v4/source/iofs/testdata/migrations/7_foobar.up.sql
deleted file mode 100644
index cdbc410ee..000000000
--- a/vendor/github.com/golang-migrate/migrate/v4/source/iofs/testdata/migrations/7_foobar.up.sql
+++ /dev/null
@@ -1,1 +0,0 @@
-7 up
diff --git a/vendor/github.com/otiai10/copy/test/data/case18/assets/README.md b/vendor/github.com/otiai10/copy/test/data/case18/assets/README.md
deleted file mode 100644
index 5570c7ff5..000000000
--- a/vendor/github.com/otiai10/copy/test/data/case18/assets/README.md
+++ /dev/null
@@ -1,1 +0,0 @@
-# Hello
\ No newline at end of file
diff --git a/vendor/github.com/rubenv/sql-migrate/test-migrations/1_initial.sql b/vendor/github.com/rubenv/sql-migrate/test-migrations/1_initial.sql
deleted file mode 100644
index cd896fbd7..000000000
--- a/vendor/github.com/rubenv/sql-migrate/test-migrations/1_initial.sql
+++ /dev/null
@@ -1,8 +0,0 @@
--- +migrate Up
--- SQL in section 'Up' is executed when this migration is applied
-CREATE TABLE people (id int);
-
-
--- +migrate Down
--- SQL section 'Down' is executed when this migration is rolled back
-DROP TABLE people;
diff --git a/vendor/github.com/rubenv/sql-migrate/test-migrations/2_record.sql b/vendor/github.com/rubenv/sql-migrate/test-migrations/2_record.sql
deleted file mode 100644
index c76d7691b..000000000
--- a/vendor/github.com/rubenv/sql-migrate/test-migrations/2_record.sql
+++ /dev/null
@@ -1,5 +0,0 @@
--- +migrate Up
-INSERT INTO people (id) VALUES (1);
-
--- +migrate Down
-DELETE FROM people WHERE id=1;