diff --git a/app/assets/javascripts/create_cluster/eks_cluster/components/create_eks_cluster.vue b/app/assets/javascripts/create_cluster/eks_cluster/components/create_eks_cluster.vue
index 3f7c2204b9f31cadc579e45735669c2bb2ebe173..eb195ad2b30af787e1d1e2a9418fb0165eff41d2 100644
--- a/app/assets/javascripts/create_cluster/eks_cluster/components/create_eks_cluster.vue
+++ b/app/assets/javascripts/create_cluster/eks_cluster/components/create_eks_cluster.vue
@@ -13,6 +13,10 @@ export default {
       type: String,
       required: true,
     },
+    namespacePerEnvironmentHelpPath: {
+      type: String,
+      required: true,
+    },
     kubernetesIntegrationHelpPath: {
       type: String,
       required: true,
@@ -40,6 +44,7 @@ export default {
     <eks-cluster-configuration-form
       v-if="hasCredentials"
       :gitlab-managed-cluster-help-path="gitlabManagedClusterHelpPath"
+      :namespace-per-environment-help-path="namespacePerEnvironmentHelpPath"
       :kubernetes-integration-help-path="kubernetesIntegrationHelpPath"
       :external-link-icon="externalLinkIcon"
     />
diff --git a/app/assets/javascripts/create_cluster/eks_cluster/components/eks_cluster_configuration_form.vue b/app/assets/javascripts/create_cluster/eks_cluster/components/eks_cluster_configuration_form.vue
index a653e228e3f19653b8da4db4749c85a64829975f..0249b485e202613689c8117669ec36fd42e3c3da 100644
--- a/app/assets/javascripts/create_cluster/eks_cluster/components/eks_cluster_configuration_form.vue
+++ b/app/assets/javascripts/create_cluster/eks_cluster/components/eks_cluster_configuration_form.vue
@@ -37,6 +37,10 @@ export default {
       type: String,
       required: true,
     },
+    namespacePerEnvironmentHelpPath: {
+      type: String,
+      required: true,
+    },
     kubernetesIntegrationHelpPath: {
       type: String,
       required: true,
@@ -60,6 +64,7 @@ export default {
       'selectedInstanceType',
       'nodeCount',
       'gitlabManagedCluster',
+      'namespacePerEnvironment',
       'isCreatingCluster',
     ]),
     ...mapGetters(['subnetValid']),
@@ -270,6 +275,20 @@ export default {
         false,
       );
     },
+    namespacePerEnvironmentHelpText() {
+      const escapedUrl = escape(this.namespacePerEnvironmentClusterHelpPath);
+
+      return sprintf(
+        s__(
+          'ClusterIntegration|Deploy each environment to its own namespace. Otherwise, environments within a project share a project-wide namespace. Note that anyone who can trigger a deployment of a namespace can read its secrets. If modified, existing environments will use their current namespaces until the cluster cache is cleared. %{startLink}More information%{endLink}',
+        ),
+        {
+          startLink: `<a href="${escapedUrl}" target="_blank" rel="noopener noreferrer">`,
+          endLink: '</a>',
+        },
+        false,
+      );
+    },
   },
   mounted() {
     this.fetchRegions();
@@ -290,6 +309,7 @@ export default {
       'setInstanceType',
       'setNodeCount',
       'setGitlabManagedCluster',
+      'setNamespacePerEnvironment',
     ]),
     ...mapRegionsActions({ fetchRegions: 'fetchItems' }),
     ...mapVpcActions({ fetchVpcs: 'fetchItems' }),
@@ -519,6 +539,14 @@ export default {
       >
       <p class="form-text text-muted" v-html="gitlabManagedHelpText"></p>
     </div>
+    <div class="form-group">
+      <gl-form-checkbox
+        :checked="namespacePerEnvironment"
+        @input="setNamespacePerEnvironment({ namespacePerEnvironment: $event })"
+        >{{ s__('ClusterIntegration|Namespace per environment') }}</gl-form-checkbox
+      >
+      <p class="form-text text-muted" v-html="namespacePerEnvironmentHelpText"></p>
+    </div>
     <div class="form-group">
       <loading-button
         class="js-create-cluster btn-success"
diff --git a/app/assets/javascripts/create_cluster/eks_cluster/index.js b/app/assets/javascripts/create_cluster/eks_cluster/index.js
index fb993a7aa598b89bbadd53e8c651af60b558f183..6d1034b4a72b5c87fd475b20db330a6172624793 100644
--- a/app/assets/javascripts/create_cluster/eks_cluster/index.js
+++ b/app/assets/javascripts/create_cluster/eks_cluster/index.js
@@ -9,6 +9,7 @@ Vue.use(Vuex);
 export default el => {
   const {
     gitlabManagedClusterHelpPath,
+    namespacePerEnvironmentHelpPath,
     kubernetesIntegrationHelpPath,
     accountAndExternalIdsHelpPath,
     createRoleArnHelpPath,
@@ -42,6 +43,7 @@ export default el => {
       return createElement('create-eks-cluster', {
         props: {
           gitlabManagedClusterHelpPath,
+          namespacePerEnvironmentHelpPath,
           kubernetesIntegrationHelpPath,
           accountAndExternalIdsHelpPath,
           createRoleArnHelpPath,
diff --git a/app/assets/javascripts/create_cluster/eks_cluster/store/actions.js b/app/assets/javascripts/create_cluster/eks_cluster/store/actions.js
index 5abff3c7831c7526668d26d06776c46d42a4826a..48c85ff627ff1340b9db8a9eab9c579bde81a8ee 100644
--- a/app/assets/javascripts/create_cluster/eks_cluster/store/actions.js
+++ b/app/assets/javascripts/create_cluster/eks_cluster/store/actions.js
@@ -55,6 +55,7 @@ export const createCluster = ({ dispatch, state }) => {
       name: state.clusterName,
       environment_scope: state.environmentScope,
       managed: state.gitlabManagedCluster,
+      namespace_per_environment: state.namespacePerEnvironment,
       provider_aws_attributes: {
         kubernetes_version: state.kubernetesVersion,
         region: state.selectedRegion,
@@ -114,6 +115,10 @@ export const setGitlabManagedCluster = ({ commit }, payload) => {
   commit(types.SET_GITLAB_MANAGED_CLUSTER, payload);
 };
 
+export const setNamespacePerEnvironment = ({ commit }, payload) => {
+  commit(types.SET_NAMESPACE_PER_ENVIRONMENT, payload);
+};
+
 export const setInstanceType = ({ commit }, payload) => {
   commit(types.SET_INSTANCE_TYPE, payload);
 };
diff --git a/app/assets/javascripts/create_cluster/eks_cluster/store/mutation_types.js b/app/assets/javascripts/create_cluster/eks_cluster/store/mutation_types.js
index 9dee6abae5fdb71e9992a43eeae77d40e177b00f..4a48195a27b683c8ed522dee08c7116f3f9b74a1 100644
--- a/app/assets/javascripts/create_cluster/eks_cluster/store/mutation_types.js
+++ b/app/assets/javascripts/create_cluster/eks_cluster/store/mutation_types.js
@@ -10,6 +10,7 @@ export const SET_SECURITY_GROUP = 'SET_SECURITY_GROUP';
 export const SET_INSTANCE_TYPE = 'SET_INSTANCE_TYPE';
 export const SET_NODE_COUNT = 'SET_NODE_COUNT';
 export const SET_GITLAB_MANAGED_CLUSTER = 'SET_GITLAB_MANAGED_CLUSTER';
+export const SET_NAMESPACE_PER_ENVIRONMENT = 'SET_NAMESPACE_PER_ENVIRONMENT';
 export const REQUEST_CREATE_ROLE = 'REQUEST_CREATE_ROLE';
 export const CREATE_ROLE_SUCCESS = 'CREATE_ROLE_SUCCESS';
 export const CREATE_ROLE_ERROR = 'CREATE_ROLE_ERROR';
diff --git a/app/assets/javascripts/create_cluster/eks_cluster/store/mutations.js b/app/assets/javascripts/create_cluster/eks_cluster/store/mutations.js
index c331d27d255c5b595aaf55dc8a18011215308492..f57236e0e31b40eb785d3d413efa4bad8f05cdf9 100644
--- a/app/assets/javascripts/create_cluster/eks_cluster/store/mutations.js
+++ b/app/assets/javascripts/create_cluster/eks_cluster/store/mutations.js
@@ -37,6 +37,9 @@ export default {
   [types.SET_GITLAB_MANAGED_CLUSTER](state, { gitlabManagedCluster }) {
     state.gitlabManagedCluster = gitlabManagedCluster;
   },
+  [types.SET_NAMESPACE_PER_ENVIRONMENT](state, { namespacePerEnvironment }) {
+    state.namespacePerEnvironment = namespacePerEnvironment;
+  },
   [types.REQUEST_CREATE_ROLE](state) {
     state.isCreatingRole = true;
     state.createRoleError = null;
diff --git a/app/assets/javascripts/create_cluster/eks_cluster/store/state.js b/app/assets/javascripts/create_cluster/eks_cluster/store/state.js
index ed51e95e434ce81fa38a351bcb748a50f8d4cc7c..c957eca1f7afbd46796ca1d17a87c98f77984e38 100644
--- a/app/assets/javascripts/create_cluster/eks_cluster/store/state.js
+++ b/app/assets/javascripts/create_cluster/eks_cluster/store/state.js
@@ -30,4 +30,5 @@ export default () => ({
   createClusterError: false,
 
   gitlabManagedCluster: true,
+  namespacePerEnvironment: true,
 });
diff --git a/app/controllers/clusters/clusters_controller.rb b/app/controllers/clusters/clusters_controller.rb
index 7006c23321c8fe94381513fb820d67cb470b240d..52719e90e04f39c1db1922f12a8287ab0cc53d6c 100644
--- a/app/controllers/clusters/clusters_controller.rb
+++ b/app/controllers/clusters/clusters_controller.rb
@@ -180,13 +180,20 @@ class Clusters::ClustersController < Clusters::BaseController
     params.permit(:cleanup)
   end
 
+  def base_permitted_cluster_params
+    [
+      :enabled,
+      :environment_scope,
+      :managed,
+      :namespace_per_environment
+    ]
+  end
+
   def update_params
     if cluster.provided_by_user?
       params.require(:cluster).permit(
-        :enabled,
+        *base_permitted_cluster_params,
         :name,
-        :environment_scope,
-        :managed,
         :base_domain,
         :management_project_id,
         platform_kubernetes_attributes: [
@@ -198,9 +205,7 @@ class Clusters::ClustersController < Clusters::BaseController
       )
     else
       params.require(:cluster).permit(
-        :enabled,
-        :environment_scope,
-        :managed,
+        *base_permitted_cluster_params,
         :base_domain,
         :management_project_id,
         platform_kubernetes_attributes: [
@@ -212,10 +217,8 @@ class Clusters::ClustersController < Clusters::BaseController
 
   def create_gcp_cluster_params
     params.require(:cluster).permit(
-      :enabled,
+      *base_permitted_cluster_params,
       :name,
-      :environment_scope,
-      :managed,
       provider_gcp_attributes: [
         :gcp_project_id,
         :zone,
@@ -232,10 +235,8 @@ class Clusters::ClustersController < Clusters::BaseController
 
   def create_aws_cluster_params
     params.require(:cluster).permit(
-      :enabled,
+      *base_permitted_cluster_params,
       :name,
-      :environment_scope,
-      :managed,
       provider_aws_attributes: [
         :kubernetes_version,
         :key_name,
@@ -255,10 +256,8 @@ class Clusters::ClustersController < Clusters::BaseController
 
   def create_user_cluster_params
     params.require(:cluster).permit(
-      :enabled,
+      *base_permitted_cluster_params,
       :name,
-      :environment_scope,
-      :managed,
       platform_kubernetes_attributes: [
         :namespace,
         :api_url,
diff --git a/app/serializers/cluster_entity.rb b/app/serializers/cluster_entity.rb
index 9872bbf80b5bc44e741a1541a5d06b33db9edcfb..b904666971e22e0dcdc14bf203d5f3ad5c699737 100644
--- a/app/serializers/cluster_entity.rb
+++ b/app/serializers/cluster_entity.rb
@@ -7,6 +7,7 @@ class ClusterEntity < Grape::Entity
   expose :enabled
   expose :environment_scope
   expose :id
+  expose :namespace_per_environment
   expose :name
   expose :nodes
   expose :provider_type
diff --git a/app/views/clusters/clusters/_provider_details_form.html.haml b/app/views/clusters/clusters/_provider_details_form.html.haml
index fcb5d4402d6ca712dcba0c0f1f32cb248494dd2e..16891c7fc21171d743fd54e213c38059b5a87ce7 100644
--- a/app/views/clusters/clusters/_provider_details_form.html.haml
+++ b/app/views/clusters/clusters/_provider_details_form.html.haml
@@ -42,11 +42,17 @@
         class: 'js-gl-managed',
         label_class: 'label-bold' }
       .form-text.text-muted
-        = s_('ClusterIntegration|Allow GitLab to manage namespace and service accounts for this cluster.')
+        = s_('ClusterIntegration|Allow GitLab to manage namespaces and service accounts for this cluster.')
         = link_to _('More information'), help_page_path('user/project/clusters/index.md', anchor: 'gitlab-managed-clusters'), target: '_blank'
 
+    .form-group
+      = field.check_box :namespace_per_environment, { label: s_('ClusterIntegration|Namespace per environment'), label_class: 'label-bold' }
+      .form-text.text-muted
+        = s_('ClusterIntegration|Deploy each environment to its own namespace. Otherwise, environments within a project share a project-wide namespace. Note that anyone who can trigger a deployment of a namespace can read its secrets. If modified, existing environments will use their current namespaces until the cluster cache is cleared.')
+        = link_to _('More information'), help_page_path('user/project/clusters/index.md', anchor: 'custom-namespace'), target: '_blank'
+
     - if cluster.allow_user_defined_namespace?
-      = render('clusters/clusters/namespace', platform_field: platform_field)
+      = render('clusters/clusters/namespace', platform_field: platform_field, field: field)
 
   .form-group
     = field.submit s_('ClusterIntegration|Save changes'), class: 'btn btn-success'
diff --git a/app/views/clusters/clusters/aws/_new.html.haml b/app/views/clusters/clusters/aws/_new.html.haml
index 3eab9b46fb3b5fcb5ff5116c89e1605ce3f119db..b1a277faae9096efbda369ed66771f243cdc76da 100644
--- a/app/views/clusters/clusters/aws/_new.html.haml
+++ b/app/views/clusters/clusters/aws/_new.html.haml
@@ -4,6 +4,7 @@
   = s_('Amazon authentication is not %{link_start}correctly configured%{link_end}. Ask your GitLab administrator if you want to use this service.').html_safe % { link_start: documentation_link_start, link_end: '<a/>'.html_safe }
 - else
   .js-create-eks-cluster-form-container{ data: { 'gitlab-managed-cluster-help-path' => help_page_path('user/project/clusters/index.md', anchor: 'gitlab-managed-clusters'),
+    'namespace-per-environment-help-path' => help_page_path('user/project/clusters/index.md', anchor: 'custom-namespace'),
     'create-role-path' => clusterable.authorize_aws_role_path,
     'create-cluster-path' => clusterable.create_aws_clusters_path,
     'account-id' => Gitlab::CurrentSettings.eks_account_id,
diff --git a/app/views/clusters/clusters/gcp/_form.html.haml b/app/views/clusters/clusters/gcp/_form.html.haml
index 434c02a5c415dc125ef2f82e0b6951ae6cd0d777..ceb6e1d46b0e3151f9f0eab6855973f97b694a89 100644
--- a/app/views/clusters/clusters/gcp/_form.html.haml
+++ b/app/views/clusters/clusters/gcp/_form.html.haml
@@ -75,9 +75,15 @@
     = field.check_box :managed, { label: s_('ClusterIntegration|GitLab-managed cluster'),
       label_class: 'label-bold' }
     .form-text.text-muted
-      = s_('ClusterIntegration|Allow GitLab to manage namespace and service accounts for this cluster.')
+      = s_('ClusterIntegration|Allow GitLab to manage namespaces and service accounts for this cluster.')
       = link_to _('More information'), help_page_path('user/project/clusters/index.md', anchor: 'gitlab-managed-clusters'), target: '_blank'
 
+  .form-group
+    = field.check_box :namespace_per_environment, { label: s_('ClusterIntegration|Namespace per environment'), label_class: 'label-bold' }
+    .form-text.text-muted
+      = s_('ClusterIntegration|Deploy each environment to its own namespace. Otherwise, environments within a project share a project-wide namespace. Note that anyone who can trigger a deployment of a namespace can read its secrets. If modified, existing environments will use their current namespaces until the cluster cache is cleared.')
+      = link_to _('More information'), help_page_path('user/project/clusters/index.md', anchor: 'custom-namespace'), target: '_blank'
+
   .form-group.js-gke-cluster-creation-submit-container
     = field.submit s_('ClusterIntegration|Create Kubernetes cluster'),
       class: 'js-gke-cluster-creation-submit btn btn-success', disabled: true
diff --git a/app/views/clusters/clusters/user/_form.html.haml b/app/views/clusters/clusters/user/_form.html.haml
index 11772107135cfbddc451a0f9a7457734764a6d8e..a6097038b2eaaa43e071f716d93bfc616da70644 100644
--- a/app/views/clusters/clusters/user/_form.html.haml
+++ b/app/views/clusters/clusters/user/_form.html.haml
@@ -46,9 +46,15 @@
       class: 'js-gl-managed',
       label_class: 'label-bold' }
     .form-text.text-muted
-      = s_('ClusterIntegration|Allow GitLab to manage namespace and service accounts for this cluster.')
+      = s_('ClusterIntegration|Allow GitLab to manage namespaces and service accounts for this cluster.')
       = link_to _('More information'), help_page_path('user/project/clusters/index.md', anchor: 'gitlab-managed-clusters'), target: '_blank'
 
+  .form-group
+    = field.check_box :namespace_per_environment, { label: s_('ClusterIntegration|Namespace per environment'), label_class: 'label-bold' }
+    .form-text.text-muted
+      = s_('ClusterIntegration|Deploy each environment to its own namespace. Otherwise, environments within a project share a project-wide namespace. Note that anyone who can trigger a deployment of a namespace can read its secrets. If modified, existing environments will use their current namespaces until the cluster cache is cleared.')
+      = link_to _('More information'), help_page_path('user/project/clusters/index.md', anchor: 'custom-namespace'), target: '_blank'
+
   = field.fields_for :platform_kubernetes, @user_cluster.platform_kubernetes do |platform_kubernetes_field|
     - if @user_cluster.allow_user_defined_namespace?
       = render('clusters/clusters/namespace', platform_field: platform_kubernetes_field)
diff --git a/changelogs/unreleased/expose-clusters-namespace-per-environment-flag.yml b/changelogs/unreleased/expose-clusters-namespace-per-environment-flag.yml
new file mode 100644
index 0000000000000000000000000000000000000000..99c630b59048f73a2dd88827a9309cecb91bbfdf
--- /dev/null
+++ b/changelogs/unreleased/expose-clusters-namespace-per-environment-flag.yml
@@ -0,0 +1,6 @@
+---
+title: Expose the option to use namespace-per-project instead of namespace-per-environment
+  for Kubernetes clusters
+merge_request: 42309
+author:
+type: changed
diff --git a/doc/user/project/clusters/index.md b/doc/user/project/clusters/index.md
index 0b755a81616f079cabf649cb5d1067bffd4a8f0b..c578af3dd35261c3ead7ad8422c4b6b6396e5a6e 100644
--- a/doc/user/project/clusters/index.md
+++ b/doc/user/project/clusters/index.md
@@ -270,20 +270,30 @@ If your cluster was created before GitLab 12.2, default `KUBE_NAMESPACE` will be
 
 ### Custom namespace
 
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27630) in GitLab 12.6.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27630) in GitLab 12.6.
+> - An option to use project-wide namespaces [was added](https://gitlab.com/gitlab-org/gitlab/-/issues/38054) in GitLab 13.5.
 
-The Kubernetes integration defaults to project-environment-specific namespaces
-of the form `<project_name>-<project_id>-<environment>` (see [Deployment
+The Kubernetes integration provides a `KUBECONFIG` with an auto-generated namespace
+to deployment jobs. It defaults to using project-environment specific namespaces
+of the form `<prefix>-<environment>`, where `<prefix>` is of the form `<project_name>-<project_id>` (see [Deployment
 variables](#deployment-variables)).
 
-For **non**-GitLab-managed clusters, the namespace can be customized using
-[`environment:kubernetes:namespace`](../../../ci/environments/index.md#configuring-kubernetes-deployments)
+The deployment namespace can be customized in a few ways:
+
+- You can choose between a **namespace per [environment](../../../ci/environments/index.md)** or a **namespace per project**. A namespace per environment is the default and recommended setting, as it prevents the mixing of resources between production and non-production environments.
+- When using a project-level cluster, you can additionally customize the namespace prefix. When using namespace-per-environment, the deployment namespace is `<prefix>-<environment>`, but otherwise just `<prefix>`.
+- For **non-managed** clusters, the auto-generated namespace is set in the `KUBECONFIG`, but the user is responsible for ensuring its existence. The value can be fully customized using [`environment:kubernetes:namespace`](../../../ci/environments/index.md#configuring-kubernetes-deployments)
 in `.gitlab-ci.yml`.
 
 NOTE: **Note:**
-When using a [GitLab-managed cluster](#gitlab-managed-clusters), the
-namespaces are created automatically prior to deployment and [can not be
-customized](https://gitlab.com/gitlab-org/gitlab/-/issues/38054).
+When you customize the namespace, existing environments remain linked to their current namespaces until you [clear the cluster cache](#clearing-the-cluster-cache).
+
+CAUTION: **Warning:**
+By default, anyone who can create a deployment job can access any CI variable within an environment's deployment job. This includes `KUBECONFIG`, which gives access to any secret available to the associated service account in your cluster.
+To keep your production credentials safe, consider using [Protected Environments](../../../ci/environments/protected_environments.md), combined with either
+
+- a GitLab-managed cluster and namespace per environment,
+- *or*, an environment-scoped cluster per protected environment (the same cluster can be added multiple times with multiple restricted service accounts).
 
 ### Integrations
 
diff --git a/lib/api/admin/instance_clusters.rb b/lib/api/admin/instance_clusters.rb
index 8208d10c0899c8c1ef8cd81247022995513f8803..0db2321199aa8511d83118f988657afd37caf355 100644
--- a/lib/api/admin/instance_clusters.rb
+++ b/lib/api/admin/instance_clusters.rb
@@ -37,6 +37,7 @@ module API
           requires :name, type: String, desc: 'Cluster name'
           optional :enabled, type: Boolean, default: true, desc: 'Determines if cluster is active or not, defaults to true'
           optional :environment_scope, default: '*', type: String, desc: 'The associated environment to the cluster'
+          optional :namespace_per_environment, default: true, type: Boolean, desc: 'Deploy each environment to a separate Kubernetes namespace'
           optional :domain, type: String, desc: 'Cluster base domain'
           optional :management_project_id, type: Integer, desc: 'The ID of the management project'
           optional :managed, type: Boolean, default: true, desc: 'Determines if GitLab will manage namespaces and service accounts for this cluster, defaults to true'
@@ -70,6 +71,7 @@ module API
           optional :name, type: String, desc: 'Cluster name'
           optional :enabled, type: Boolean, desc: 'Enable or disable Gitlab\'s connection to your Kubernetes cluster'
           optional :environment_scope, type: String, desc: 'The associated environment to the cluster'
+          optional :namespace_per_environment, default: true, type: Boolean, desc: 'Deploy each environment to a separate Kubernetes namespace'
           optional :domain, type: String, desc: 'Cluster base domain'
           optional :management_project_id, type: Integer, desc: 'The ID of the management project'
           optional :platform_kubernetes_attributes, type: Hash, desc: %q(Platform Kubernetes data) do
diff --git a/lib/api/entities/cluster.rb b/lib/api/entities/cluster.rb
index 4cb54e988ce77ef62e21587b1b27bea0ffa25933..67459092a33411ee29060a2cae417bb37f75cc0d 100644
--- a/lib/api/entities/cluster.rb
+++ b/lib/api/entities/cluster.rb
@@ -4,7 +4,7 @@ module API
   module Entities
     class Cluster < Grape::Entity
       expose :id, :name, :created_at, :domain
-      expose :provider_type, :platform_type, :environment_scope, :cluster_type
+      expose :provider_type, :platform_type, :environment_scope, :cluster_type, :namespace_per_environment
       expose :user, using: Entities::UserBasic
       expose :platform_kubernetes, using: Entities::Platform::Kubernetes
       expose :provider_gcp, using: Entities::Provider::Gcp
diff --git a/lib/api/group_clusters.rb b/lib/api/group_clusters.rb
index ae41d9f13b81e812871c0512c2507f25e959b229..77095ee62e0b55a9d5db4e116507b02acdd4e237 100644
--- a/lib/api/group_clusters.rb
+++ b/lib/api/group_clusters.rb
@@ -41,6 +41,7 @@ module API
         requires :name, type: String, desc: 'Cluster name'
         optional :enabled, type: Boolean, default: true, desc: 'Determines if cluster is active or not, defaults to true'
         optional :environment_scope, default: '*', type: String, desc: 'The associated environment to the cluster'
+        optional :namespace_per_environment, default: true, type: Boolean, desc: 'Deploy each environment to a separate Kubernetes namespace'
         optional :domain, type: String, desc: 'Cluster base domain'
         optional :management_project_id, type: Integer, desc: 'The ID of the management project'
         optional :managed, type: Boolean, default: true, desc: 'Determines if GitLab will manage namespaces and service accounts for this cluster, defaults to true'
@@ -74,6 +75,7 @@ module API
         optional :name, type: String, desc: 'Cluster name'
         optional :domain, type: String, desc: 'Cluster base domain'
         optional :environment_scope, type: String, desc: 'The associated environment to the cluster'
+        optional :namespace_per_environment, default: true, type: Boolean, desc: 'Deploy each environment to a separate Kubernetes namespace'
         optional :management_project_id, type: Integer, desc: 'The ID of the management project'
         optional :platform_kubernetes_attributes, type: Hash, desc: %q(Platform Kubernetes data) do
           optional :api_url, type: String, desc: 'URL to access the Kubernetes API'
diff --git a/lib/api/project_clusters.rb b/lib/api/project_clusters.rb
index 0e5605984e63f56dfbe3fc17f719db3c2abef7f4..6f189110d76b5f4d79cebb37658dc05e346aa8e6 100644
--- a/lib/api/project_clusters.rb
+++ b/lib/api/project_clusters.rb
@@ -45,6 +45,7 @@ module API
         optional :enabled, type: Boolean, default: true, desc: 'Determines if cluster is active or not, defaults to true'
         optional :domain, type: String, desc: 'Cluster base domain'
         optional :environment_scope, default: '*', type: String, desc: 'The associated environment to the cluster'
+        optional :namespace_per_environment, default: true, type: Boolean, desc: 'Deploy each environment to a separate Kubernetes namespace'
         optional :management_project_id, type: Integer, desc: 'The ID of the management project'
         optional :managed, type: Boolean, default: true, desc: 'Determines if GitLab will manage namespaces and service accounts for this cluster, defaults to true'
         requires :platform_kubernetes_attributes, type: Hash, desc: %q(Platform Kubernetes data) do
@@ -78,6 +79,7 @@ module API
         optional :name, type: String, desc: 'Cluster name'
         optional :domain, type: String, desc: 'Cluster base domain'
         optional :environment_scope, type: String, desc: 'The associated environment to the cluster'
+        optional :namespace_per_environment, default: true, type: Boolean, desc: 'Deploy each environment to a separate Kubernetes namespace'
         optional :management_project_id, type: Integer, desc: 'The ID of the management project'
         optional :platform_kubernetes_attributes, type: Hash, desc: %q(Platform Kubernetes data) do
           optional :api_url, type: String, desc: 'URL to access the Kubernetes API'
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 600e5833438b3dc598a21640250b5bd2406d05d5..23d5aa9076d8214290baec21d348ec76f4a31dd6 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -5379,10 +5379,10 @@ msgstr ""
 msgid "ClusterIntegration|All installed applications and related resources"
 msgstr ""
 
-msgid "ClusterIntegration|Allow GitLab to manage namespace and service accounts for this cluster."
+msgid "ClusterIntegration|Allow GitLab to manage namespace and service accounts for this cluster. %{startLink}More information%{endLink}"
 msgstr ""
 
-msgid "ClusterIntegration|Allow GitLab to manage namespace and service accounts for this cluster. %{startLink}More information%{endLink}"
+msgid "ClusterIntegration|Allow GitLab to manage namespaces and service accounts for this cluster."
 msgstr ""
 
 msgid "ClusterIntegration|Alternatively, "
@@ -5565,6 +5565,12 @@ msgstr ""
 msgid "ClusterIntegration|Deletes all GitLab resources attached to this cluster during removal"
 msgstr ""
 
+msgid "ClusterIntegration|Deploy each environment to its own namespace. Otherwise, environments within a project share a project-wide namespace. Note that anyone who can trigger a deployment of a namespace can read its secrets. If modified, existing environments will use their current namespaces until the cluster cache is cleared."
+msgstr ""
+
+msgid "ClusterIntegration|Deploy each environment to its own namespace. Otherwise, environments within a project share a project-wide namespace. Note that anyone who can trigger a deployment of a namespace can read its secrets. If modified, existing environments will use their current namespaces until the cluster cache is cleared. %{startLink}More information%{endLink}"
+msgstr ""
+
 msgid "ClusterIntegration|Did you know?"
 msgstr ""
 
@@ -5826,6 +5832,9 @@ msgstr ""
 msgid "ClusterIntegration|Manage your Kubernetes cluster by visiting %{provider_link}"
 msgstr ""
 
+msgid "ClusterIntegration|Namespace per environment"
+msgstr ""
+
 msgid "ClusterIntegration|No IAM Roles found"
 msgstr ""
 
diff --git a/spec/controllers/admin/clusters_controller_spec.rb b/spec/controllers/admin/clusters_controller_spec.rb
index d2a569a9d488a26837f273ebe134351582d3895a..69bdc79c5f550a998a3f7264e23d37bd30279894 100644
--- a/spec/controllers/admin/clusters_controller_spec.rb
+++ b/spec/controllers/admin/clusters_controller_spec.rb
@@ -416,6 +416,7 @@ RSpec.describe Admin::ClustersController do
           expect(cluster).to be_user
           expect(cluster).to be_kubernetes
           expect(cluster).to be_platform_kubernetes_rbac
+          expect(cluster).to be_namespace_per_environment
         end
       end
     end
@@ -585,6 +586,7 @@ RSpec.describe Admin::ClustersController do
           enabled: false,
           name: 'my-new-cluster-name',
           managed: false,
+          namespace_per_environment: false,
           base_domain: domain
         }
       }
@@ -599,6 +601,7 @@ RSpec.describe Admin::ClustersController do
       expect(cluster.enabled).to be_falsey
       expect(cluster.name).to eq('my-new-cluster-name')
       expect(cluster).not_to be_managed
+      expect(cluster).not_to be_namespace_per_environment
       expect(cluster.domain).to eq('test-domain.com')
     end
 
@@ -624,6 +627,7 @@ RSpec.describe Admin::ClustersController do
                 enabled: false,
                 name: 'my-new-cluster-name',
                 managed: false,
+                namespace_per_environment: false,
                 domain: domain
               }
             }
@@ -637,6 +641,7 @@ RSpec.describe Admin::ClustersController do
             expect(cluster.enabled).to be_falsey
             expect(cluster.name).to eq('my-new-cluster-name')
             expect(cluster).not_to be_managed
+            expect(cluster).not_to be_namespace_per_environment
           end
         end
 
diff --git a/spec/controllers/groups/clusters_controller_spec.rb b/spec/controllers/groups/clusters_controller_spec.rb
index 81d5bc7770fb0913a509e5b2f9eb6cf9efc9fa1e..140b7b0f2a8ee5d1166f4bafb8a929237a2d40ec 100644
--- a/spec/controllers/groups/clusters_controller_spec.rb
+++ b/spec/controllers/groups/clusters_controller_spec.rb
@@ -271,6 +271,7 @@ RSpec.describe Groups::ClustersController do
           expect(cluster).to be_kubernetes
           expect(cluster.provider_gcp).to be_legacy_abac
           expect(cluster).to be_managed
+          expect(cluster).to be_namespace_per_environment
         end
 
         context 'when legacy_abac param is false' do
@@ -358,6 +359,7 @@ RSpec.describe Groups::ClustersController do
           expect(cluster).to be_user
           expect(cluster).to be_kubernetes
           expect(cluster).to be_managed
+          expect(cluster).to be_namespace_per_environment
         end
       end
 
@@ -387,6 +389,7 @@ RSpec.describe Groups::ClustersController do
           expect(cluster).to be_user
           expect(cluster).to be_kubernetes
           expect(cluster).to be_platform_kubernetes_rbac
+          expect(cluster).to be_namespace_per_environment
         end
       end
 
@@ -716,6 +719,7 @@ RSpec.describe Groups::ClustersController do
                 enabled: false,
                 name: 'my-new-cluster-name',
                 managed: false,
+                namespace_per_environment: false,
                 domain: domain
               }
             }
@@ -729,6 +733,7 @@ RSpec.describe Groups::ClustersController do
             expect(cluster.enabled).to be_falsey
             expect(cluster.name).to eq('my-new-cluster-name')
             expect(cluster).not_to be_managed
+            expect(cluster).not_to be_namespace_per_environment
           end
         end
 
diff --git a/spec/controllers/projects/clusters_controller_spec.rb b/spec/controllers/projects/clusters_controller_spec.rb
index 51a451570c5cd3d568aa3fb0b6cc831c1250c181..52cd6869b04cdfeb2b23e9bf5994061a0f989025 100644
--- a/spec/controllers/projects/clusters_controller_spec.rb
+++ b/spec/controllers/projects/clusters_controller_spec.rb
@@ -251,6 +251,7 @@ RSpec.describe Projects::ClustersController do
         cluster: {
           name: 'new-cluster',
           managed: '1',
+          namespace_per_environment: '0',
           provider_gcp_attributes: {
             gcp_project_id: 'gcp-project-12345',
             legacy_abac: legacy_abac_param
@@ -278,6 +279,7 @@ RSpec.describe Projects::ClustersController do
           expect(project.clusters.first).to be_kubernetes
           expect(project.clusters.first.provider_gcp).to be_legacy_abac
           expect(project.clusters.first.managed?).to be_truthy
+          expect(project.clusters.first.namespace_per_environment?).to be_falsy
         end
 
         context 'when legacy_abac param is false' do
@@ -369,6 +371,7 @@ RSpec.describe Projects::ClustersController do
 
           expect(project.clusters.first).to be_user
           expect(project.clusters.first).to be_kubernetes
+          expect(project.clusters.first).to be_namespace_per_environment
         end
       end
 
@@ -400,6 +403,7 @@ RSpec.describe Projects::ClustersController do
           expect(cluster).to be_user
           expect(cluster).to be_kubernetes
           expect(cluster).to be_platform_kubernetes_rbac
+          expect(cluster).to be_namespace_per_environment
         end
       end
 
@@ -726,6 +730,7 @@ RSpec.describe Projects::ClustersController do
           enabled: false,
           name: 'my-new-cluster-name',
           managed: false,
+          namespace_per_environment: false,
           platform_kubernetes_attributes: {
             namespace: 'my-namespace'
           }
@@ -742,6 +747,7 @@ RSpec.describe Projects::ClustersController do
       expect(cluster.enabled).to be_falsey
       expect(cluster.name).to eq('my-new-cluster-name')
       expect(cluster).not_to be_managed
+      expect(cluster).not_to be_namespace_per_environment
       expect(cluster.platform_kubernetes.namespace).to eq('my-namespace')
     end
 
diff --git a/spec/features/groups/clusters/user_spec.rb b/spec/features/groups/clusters/user_spec.rb
index 90253451d6b4ea5d21c18ac2aac491f29ace4fc9..0a1d2284831b8f7cbe42474331917545bf095c06 100644
--- a/spec/features/groups/clusters/user_spec.rb
+++ b/spec/features/groups/clusters/user_spec.rb
@@ -66,6 +66,10 @@ RSpec.describe 'User Cluster', :js do
           expect(page.find_field('cluster[platform_kubernetes_attributes][authorization_type]', disabled: true)).to be_checked
         end
       end
+
+      it 'user sees namespace per environment is enabled by default' do
+        expect(page).to have_checked_field('Namespace per environment')
+      end
     end
 
     context 'when user filled form with invalid parameters' do
diff --git a/spec/features/projects/clusters/user_spec.rb b/spec/features/projects/clusters/user_spec.rb
index 9d0dc65093e7af921d8a810774f232bfa4ad0539..97d2f20403652a3865fd66247851ab69569fcd7e 100644
--- a/spec/features/projects/clusters/user_spec.rb
+++ b/spec/features/projects/clusters/user_spec.rb
@@ -52,6 +52,10 @@ RSpec.describe 'User Cluster', :js do
       it 'user sees RBAC is enabled by default' do
         expect(page).to have_checked_field('RBAC-enabled cluster')
       end
+
+      it 'user sees namespace per environment is enabled by default' do
+        expect(page).to have_checked_field('Namespace per environment')
+      end
     end
 
     context 'when user filled form with invalid parameters' do
diff --git a/spec/frontend/create_cluster/eks_cluster/components/create_eks_cluster_spec.js b/spec/frontend/create_cluster/eks_cluster/components/create_eks_cluster_spec.js
index 4bf3ac430f5f063bdd53fa3e801c2b1af2a8b4fe..e0913fe2e88223a09cdce61410576f8d9e8efab8 100644
--- a/spec/frontend/create_cluster/eks_cluster/components/create_eks_cluster_spec.js
+++ b/spec/frontend/create_cluster/eks_cluster/components/create_eks_cluster_spec.js
@@ -12,6 +12,7 @@ describe('CreateEksCluster', () => {
   let vm;
   let state;
   const gitlabManagedClusterHelpPath = 'gitlab-managed-cluster-help-path';
+  const namespacePerEnvironmentHelpPath = 'namespace-per-environment-help-path';
   const accountAndExternalIdsHelpPath = 'account-and-external-id-help-path';
   const createRoleArnHelpPath = 'role-arn-help-path';
   const kubernetesIntegrationHelpPath = 'kubernetes-integration';
@@ -26,6 +27,7 @@ describe('CreateEksCluster', () => {
     vm = shallowMount(CreateEksCluster, {
       propsData: {
         gitlabManagedClusterHelpPath,
+        namespacePerEnvironmentHelpPath,
         accountAndExternalIdsHelpPath,
         createRoleArnHelpPath,
         externalLinkIcon,
@@ -53,6 +55,12 @@ describe('CreateEksCluster', () => {
         );
       });
 
+      it('help url for namespace per environment cluster documentation', () => {
+        expect(vm.find(EksClusterConfigurationForm).props('namespacePerEnvironmentHelpPath')).toBe(
+          namespacePerEnvironmentHelpPath,
+        );
+      });
+
       it('help url for gitlab managed cluster documentation', () => {
         expect(vm.find(EksClusterConfigurationForm).props('kubernetesIntegrationHelpPath')).toBe(
           kubernetesIntegrationHelpPath,
diff --git a/spec/frontend/create_cluster/eks_cluster/components/eks_cluster_configuration_form_spec.js b/spec/frontend/create_cluster/eks_cluster/components/eks_cluster_configuration_form_spec.js
index d7dd7072f6740cf069ca9179daa6036076b5203a..2600415fc9fd5f50497a179a48682eb816e273ea 100644
--- a/spec/frontend/create_cluster/eks_cluster/components/eks_cluster_configuration_form_spec.js
+++ b/spec/frontend/create_cluster/eks_cluster/components/eks_cluster_configuration_form_spec.js
@@ -169,6 +169,7 @@ describe('EksClusterConfigurationForm', () => {
       store,
       propsData: {
         gitlabManagedClusterHelpPath: '',
+        namespacePerEnvironmentHelpPath: '',
         kubernetesIntegrationHelpPath: '',
         externalLinkIcon: '',
       },
diff --git a/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js b/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js
index ed75388879081fe32f3d9a7c3f28b43b8aa43c06..f929216689a4f82281553d73e0234e8ab7b7aab4 100644
--- a/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js
+++ b/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js
@@ -14,6 +14,7 @@ import {
   SET_ROLE,
   SET_SECURITY_GROUP,
   SET_GITLAB_MANAGED_CLUSTER,
+  SET_NAMESPACE_PER_ENVIRONMENT,
   SET_INSTANCE_TYPE,
   SET_NODE_COUNT,
   REQUEST_CREATE_ROLE,
@@ -40,6 +41,7 @@ describe('EKS Cluster Store Actions', () => {
   let instanceType;
   let nodeCount;
   let gitlabManagedCluster;
+  let namespacePerEnvironment;
   let mock;
   let state;
   let newClusterUrl;
@@ -57,6 +59,7 @@ describe('EKS Cluster Store Actions', () => {
     instanceType = 'small-1';
     nodeCount = '5';
     gitlabManagedCluster = true;
+    namespacePerEnvironment = true;
 
     newClusterUrl = '/clusters/1';
 
@@ -76,19 +79,20 @@ describe('EKS Cluster Store Actions', () => {
   });
 
   it.each`
-    action                       | mutation                      | payload                  | payloadDescription
-    ${'setClusterName'}          | ${SET_CLUSTER_NAME}           | ${{ clusterName }}       | ${'cluster name'}
-    ${'setEnvironmentScope'}     | ${SET_ENVIRONMENT_SCOPE}      | ${{ environmentScope }}  | ${'environment scope'}
-    ${'setKubernetesVersion'}    | ${SET_KUBERNETES_VERSION}     | ${{ kubernetesVersion }} | ${'kubernetes version'}
-    ${'setRole'}                 | ${SET_ROLE}                   | ${{ role }}              | ${'role'}
-    ${'setRegion'}               | ${SET_REGION}                 | ${{ region }}            | ${'region'}
-    ${'setKeyPair'}              | ${SET_KEY_PAIR}               | ${{ keyPair }}           | ${'key pair'}
-    ${'setVpc'}                  | ${SET_VPC}                    | ${{ vpc }}               | ${'vpc'}
-    ${'setSubnet'}               | ${SET_SUBNET}                 | ${{ subnet }}            | ${'subnet'}
-    ${'setSecurityGroup'}        | ${SET_SECURITY_GROUP}         | ${{ securityGroup }}     | ${'securityGroup'}
-    ${'setInstanceType'}         | ${SET_INSTANCE_TYPE}          | ${{ instanceType }}      | ${'instance type'}
-    ${'setNodeCount'}            | ${SET_NODE_COUNT}             | ${{ nodeCount }}         | ${'node count'}
-    ${'setGitlabManagedCluster'} | ${SET_GITLAB_MANAGED_CLUSTER} | ${gitlabManagedCluster}  | ${'gitlab managed cluster'}
+    action                          | mutation                         | payload                    | payloadDescription
+    ${'setClusterName'}             | ${SET_CLUSTER_NAME}              | ${{ clusterName }}         | ${'cluster name'}
+    ${'setEnvironmentScope'}        | ${SET_ENVIRONMENT_SCOPE}         | ${{ environmentScope }}    | ${'environment scope'}
+    ${'setKubernetesVersion'}       | ${SET_KUBERNETES_VERSION}        | ${{ kubernetesVersion }}   | ${'kubernetes version'}
+    ${'setRole'}                    | ${SET_ROLE}                      | ${{ role }}                | ${'role'}
+    ${'setRegion'}                  | ${SET_REGION}                    | ${{ region }}              | ${'region'}
+    ${'setKeyPair'}                 | ${SET_KEY_PAIR}                  | ${{ keyPair }}             | ${'key pair'}
+    ${'setVpc'}                     | ${SET_VPC}                       | ${{ vpc }}                 | ${'vpc'}
+    ${'setSubnet'}                  | ${SET_SUBNET}                    | ${{ subnet }}              | ${'subnet'}
+    ${'setSecurityGroup'}           | ${SET_SECURITY_GROUP}            | ${{ securityGroup }}       | ${'securityGroup'}
+    ${'setInstanceType'}            | ${SET_INSTANCE_TYPE}             | ${{ instanceType }}        | ${'instance type'}
+    ${'setNodeCount'}               | ${SET_NODE_COUNT}                | ${{ nodeCount }}           | ${'node count'}
+    ${'setGitlabManagedCluster'}    | ${SET_GITLAB_MANAGED_CLUSTER}    | ${gitlabManagedCluster}    | ${'gitlab managed cluster'}
+    ${'setNamespacePerEnvironment'} | ${SET_NAMESPACE_PER_ENVIRONMENT} | ${namespacePerEnvironment} | ${'namespace per environment'}
   `(`$action commits $mutation with $payloadDescription payload`, data => {
     const { action, mutation, payload } = data;
 
@@ -179,6 +183,7 @@ describe('EKS Cluster Store Actions', () => {
         name: clusterName,
         environment_scope: environmentScope,
         managed: gitlabManagedCluster,
+        namespace_per_environment: namespacePerEnvironment,
         provider_aws_attributes: {
           kubernetes_version: kubernetesVersion,
           region,
@@ -204,6 +209,7 @@ describe('EKS Cluster Store Actions', () => {
         selectedInstanceType: instanceType,
         nodeCount,
         gitlabManagedCluster,
+        namespacePerEnvironment,
       });
     });
 
diff --git a/spec/models/clusters/cluster_spec.rb b/spec/models/clusters/cluster_spec.rb
index 024539e34ecb45418be5b597b65fc83a9df79d7a..dd9b96f39ade7d76e817b1a0a7ad2d73932b4382 100644
--- a/spec/models/clusters/cluster_spec.rb
+++ b/spec/models/clusters/cluster_spec.rb
@@ -47,6 +47,7 @@ RSpec.describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
   it { is_expected.to delegate_method(:external_hostname).to(:application_ingress).with_prefix }
 
   it { is_expected.to respond_to :project }
+  it { is_expected.to be_namespace_per_environment }
 
   describe 'applications have inverse_of: :cluster option' do
     let(:cluster) { create(:cluster) }
diff --git a/spec/requests/api/admin/instance_clusters_spec.rb b/spec/requests/api/admin/instance_clusters_spec.rb
index b68541b5d9237c1255c4b70a125763cf3407955e..9d0661089a9962ffb8120e4136a90ef910d52ef2 100644
--- a/spec/requests/api/admin/instance_clusters_spec.rb
+++ b/spec/requests/api/admin/instance_clusters_spec.rb
@@ -162,6 +162,7 @@ RSpec.describe ::API::Admin::InstanceClusters do
         name: 'test-instance-cluster',
         domain: 'domain.example.com',
         managed: false,
+        namespace_per_environment: false,
         platform_kubernetes_attributes: platform_kubernetes_attributes,
         clusterable: clusterable
       }
@@ -206,6 +207,7 @@ RSpec.describe ::API::Admin::InstanceClusters do
           expect(cluster_result.enabled).to eq(true)
           expect(platform_kubernetes.authorization_type).to eq('rbac')
           expect(cluster_result.managed).to be_falsy
+          expect(cluster_result.namespace_per_environment).to eq(false)
           expect(platform_kubernetes.api_url).to eq("https://example.com")
           expect(platform_kubernetes.token).to eq('sample-token')
         end
@@ -235,6 +237,22 @@ RSpec.describe ::API::Admin::InstanceClusters do
           end
         end
 
+        context 'when namespace_per_environment is not set' do
+          let(:cluster_params) do
+            {
+              name: 'test-cluster',
+              domain: 'domain.example.com',
+              platform_kubernetes_attributes: platform_kubernetes_attributes
+            }
+          end
+
+          it 'defaults to true' do
+            cluster_result = Clusters::Cluster.find(json_response['id'])
+
+            expect(cluster_result).to be_namespace_per_environment
+          end
+        end
+
         context 'when an instance cluster already exists' do
           it 'allows user to add multiple clusters' do
             post api('/admin/clusters/add', admin_user), params: multiple_cluster_params
diff --git a/spec/requests/api/group_clusters_spec.rb b/spec/requests/api/group_clusters_spec.rb
index 068af1485e28b6d97496fec004b9f2dc9b0874fd..eb21ae9468cf4cecf3a5b01f70deb5b39e5b9cfd 100644
--- a/spec/requests/api/group_clusters_spec.rb
+++ b/spec/requests/api/group_clusters_spec.rb
@@ -172,6 +172,7 @@ RSpec.describe API::GroupClusters do
         name: 'test-cluster',
         domain: 'domain.example.com',
         managed: false,
+        namespace_per_environment: false,
         platform_kubernetes_attributes: platform_kubernetes_attributes,
         management_project_id: management_project_id
       }
@@ -206,6 +207,7 @@ RSpec.describe API::GroupClusters do
           expect(cluster_result.domain).to eq('domain.example.com')
           expect(cluster_result.managed).to be_falsy
           expect(cluster_result.management_project_id).to eq management_project_id
+          expect(cluster_result.namespace_per_environment).to eq(false)
           expect(platform_kubernetes.rbac?).to be_truthy
           expect(platform_kubernetes.api_url).to eq(api_url)
           expect(platform_kubernetes.token).to eq('sample-token')
@@ -237,6 +239,22 @@ RSpec.describe API::GroupClusters do
         end
       end
 
+      context 'when namespace_per_environment is not set' do
+        let(:cluster_params) do
+          {
+            name: 'test-cluster',
+            domain: 'domain.example.com',
+            platform_kubernetes_attributes: platform_kubernetes_attributes
+          }
+        end
+
+        it 'defaults to true' do
+          cluster_result = Clusters::Cluster.find(json_response['id'])
+
+          expect(cluster_result).to be_namespace_per_environment
+        end
+      end
+
       context 'current user does not have access to management_project_id' do
         let(:management_project_id) { create(:project).id }
 
diff --git a/spec/requests/api/project_clusters_spec.rb b/spec/requests/api/project_clusters_spec.rb
index ff35e3804761cdf4f99c29d582409eb15c1220e3..7b37862af74ee1b65a83e6a62f12857d24a26af0 100644
--- a/spec/requests/api/project_clusters_spec.rb
+++ b/spec/requests/api/project_clusters_spec.rb
@@ -171,6 +171,7 @@ RSpec.describe API::ProjectClusters do
         name: 'test-cluster',
         domain: 'domain.example.com',
         managed: false,
+        namespace_per_environment: false,
         platform_kubernetes_attributes: platform_kubernetes_attributes,
         management_project_id: management_project_id
       }
@@ -202,6 +203,7 @@ RSpec.describe API::ProjectClusters do
           expect(cluster_result.domain).to eq('domain.example.com')
           expect(cluster_result.managed).to be_falsy
           expect(cluster_result.management_project_id).to eq management_project_id
+          expect(cluster_result.namespace_per_environment).to eq(false)
           expect(platform_kubernetes.rbac?).to be_truthy
           expect(platform_kubernetes.api_url).to eq(api_url)
           expect(platform_kubernetes.namespace).to eq(namespace)
@@ -235,6 +237,22 @@ RSpec.describe API::ProjectClusters do
         end
       end
 
+      context 'when namespace_per_environment is not set' do
+        let(:cluster_params) do
+          {
+            name: 'test-cluster',
+            domain: 'domain.example.com',
+            platform_kubernetes_attributes: platform_kubernetes_attributes
+          }
+        end
+
+        it 'defaults to true' do
+          cluster_result = Clusters::Cluster.find(json_response['id'])
+
+          expect(cluster_result).to be_namespace_per_environment
+        end
+      end
+
       context 'current user does not have access to management_project_id' do
         let(:management_project_id) { create(:project).id }