diff --git a/go.mod b/go.mod
index 983ecd49..e10c48a8 100644
--- a/go.mod
+++ b/go.mod
@@ -22,7 +22,7 @@ require (
 	github.com/open-policy-agent/gatekeeper/v3 v3.15.1
 	github.com/orcaman/concurrent-map/v2 v2.0.1
 	github.com/pkg/errors v0.9.1
-	github.com/pluralsh/console-client-go v0.11.2
+	github.com/pluralsh/console-client-go v0.11.8
 	github.com/pluralsh/controller-reconcile-helper v0.0.4
 	github.com/pluralsh/gophoenix v0.1.3-0.20231201014135-dff1b4309e34
 	github.com/pluralsh/polly v0.1.10
diff --git a/go.sum b/go.sum
index f584b369..d95db83a 100644
--- a/go.sum
+++ b/go.sum
@@ -532,8 +532,8 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
-github.com/pluralsh/console-client-go v0.11.2 h1:mxWaLRKlYr3MsVA4ViYxj/FV/5JjCE1NvBjBlDvAbj8=
-github.com/pluralsh/console-client-go v0.11.2/go.mod h1:eyCiLA44YbXiYyJh8303jk5JdPkt9McgCo5kBjk4lKo=
+github.com/pluralsh/console-client-go v0.11.8 h1:QRr9/IEEEHUOkBLZefRsjcZ598JnfGAkmx9ZoIBSmb0=
+github.com/pluralsh/console-client-go v0.11.8/go.mod h1:eyCiLA44YbXiYyJh8303jk5JdPkt9McgCo5kBjk4lKo=
 github.com/pluralsh/controller-reconcile-helper v0.0.4 h1:1o+7qYSyoeqKFjx+WgQTxDz4Q2VMpzprJIIKShxqG0E=
 github.com/pluralsh/controller-reconcile-helper v0.0.4/go.mod h1:AfY0gtteD6veBjmB6jiRx/aR4yevEf6K0M13/pGan/s=
 github.com/pluralsh/gophoenix v0.1.3-0.20231201014135-dff1b4309e34 h1:ab2PN+6if/Aq3/sJM0AVdy1SYuMAnq4g20VaKhTm/Bw=
diff --git a/pkg/controller/service/reconciler.go b/pkg/controller/service/reconciler.go
index 7e245807..d301c224 100644
--- a/pkg/controller/service/reconciler.go
+++ b/pkg/controller/service/reconciler.go
@@ -9,6 +9,7 @@ import (
 	console "github.com/pluralsh/console-client-go"
 	"github.com/pluralsh/polly/algorithms"
 	"github.com/samber/lo"
+	"k8s.io/apimachinery/pkg/api/meta"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 	"k8s.io/apimachinery/pkg/runtime/schema"
@@ -20,6 +21,7 @@ import (
 	"sigs.k8s.io/cli-utils/pkg/apply"
 	"sigs.k8s.io/cli-utils/pkg/common"
 	"sigs.k8s.io/cli-utils/pkg/inventory"
+	"sigs.k8s.io/cli-utils/pkg/object"
 	"sigs.k8s.io/controller-runtime/pkg/log"
 	"sigs.k8s.io/controller-runtime/pkg/reconcile"
 
@@ -61,6 +63,7 @@ type ServiceReconciler struct {
 	UtilFactory      util.Factory
 	RestoreNamespace string
 
+	mapper          meta.RESTMapper
 	discoveryClient *discovery.DiscoveryClient
 	pinger          *ping.Pinger
 	ctx             context.Context
@@ -86,7 +89,10 @@ func NewServiceReconciler(ctx context.Context, consoleClient client.Client, conf
 	manifestCache := manifests.NewCache(manifestTTL, deployToken, consoleURL)
 
 	f := utils.NewFactory(config)
-
+	mapper, err := f.ToRESTMapper()
+	if err != nil {
+		return nil, err
+	}
 	cs, err := f.KubernetesClientSet()
 	if err != nil {
 		return nil, err
@@ -127,6 +133,7 @@ func NewServiceReconciler(ctx context.Context, consoleClient client.Client, conf
 		pinger:           ping.New(consoleClient, discoveryClient, f),
 		RestoreNamespace: restoreNamespace,
 		ctx:              ctx,
+		mapper:           mapper,
 	}, nil
 }
 
@@ -188,6 +195,49 @@ func newDestroyer(invFactory inventory.ClientFactory, f util.Factory) (*apply.De
 		Build()
 }
 
+func (s *ServiceReconciler) enforceNamespace(objs []*unstructured.Unstructured, svc *console.GetServiceDeploymentForAgent_ServiceDeployment) error {
+	if svc == nil {
+		return nil
+	}
+	if svc.SyncConfig == nil {
+		return nil
+	}
+	if svc.SyncConfig.EnforceNamespace == nil {
+		return nil
+	}
+	if !*svc.SyncConfig.EnforceNamespace {
+		return nil
+	}
+
+	var crdObjs []*unstructured.Unstructured
+	// find any crds in the set of resources.
+	for _, obj := range objs {
+		if object.IsCRD(obj) {
+			crdObjs = append(crdObjs, obj)
+		}
+	}
+	for _, obj := range objs {
+
+		// Look up the scope of the resource so we know if the resource
+		// should have a namespace set or not.
+		scope, err := object.LookupResourceScope(obj, crdObjs, s.mapper)
+		if err != nil {
+			return err
+		}
+
+		switch scope {
+		case meta.RESTScopeNamespace:
+			obj.SetNamespace(svc.Namespace)
+		case meta.RESTScopeRoot:
+			return fmt.Errorf("the service %s with 'enforceNamespace' flag has cluster-scoped resources", svc.ID)
+		default:
+			return fmt.Errorf("unknown RESTScope %q", scope.Name())
+		}
+	}
+
+	return nil
+}
+
 func postProcess(mans []*unstructured.Unstructured) []*unstructured.Unstructured {
 	return lo.Map(mans, func(man *unstructured.Unstructured, ind int) *unstructured.Unstructured {
 		labels := man.GetLabels()
@@ -372,6 +422,11 @@ func (s *ServiceReconciler) Reconcile(ctx context.Context, id string) (result re
 		return
 	}
 
+	err = s.enforceNamespace(manifests, svc)
+	if err != nil {
+		return
+	}
+
 	options := apply.ApplierOptions{
 		ServerSideOptions: common.ServerSideOptions{
 			ServerSideApply: true,