> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Administrative Boundaries Between Resources Using Namespaces

### More Info:

Use namespaces to isolate your Kubernetes objects.

### Risk Level

Low

### Address

Security

### Compliance Standards

* APRA CPS 234 (Australia)
* BSI C5 (Germany)
* Brazil LGPD
* CCPA / CPRA (California)
* CIS Critical Security Controls v8
* CIS GKE
* CMMC 2.0
* CSA Cloud Controls Matrix v4
* DPDPA
* Digital Operational Resilience Act (EU)
* Essential 8
* ISO/IEC 27017
* ISO/IEC 27018
* ISO/IEC 27701
* KSA PDPL
* MAS Technology Risk Management (Singapore)
* MITRE ATT\&CK (Cloud)
* NIST SP 800-171
* NYDFS 23 NYCRR 500
* SWIFT Customer Security Controls Framework
* Sarbanes-Oxley IT General Controls
* UK NCSC Cyber Assessment Framework

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **Inventory existing namespaces and workloads**
           * Run (on any machine with kubectl access):
             ```sh theme={null}
             kubectl get namespaces
             kubectl get all --all-namespaces
             ```
           * Identify which applications, teams, and environments (dev/test/stage/prod) currently share a namespace (especially `default`).

        2. **Identify isolation requirements and desired boundaries**
           * With your application/ops teams, decide how you want to separate:
             * By environment: e.g. `dev`, `stage`, `prod`
             * By team or business unit: e.g. `payments`, `analytics`
             * By application: e.g. `web-frontend`, `orders-service`
           * Note which existing workloads in `default` or other shared namespaces should move into their own dedicated namespace(s).

        3. **Check for objects incorrectly living in shared/default namespaces**
           * List objects in `default` and any “catch-all” namespaces:
             ```sh theme={null}
             kubectl get all -n default
             kubectl get all -n kube-system
             ```
           * Flag any non-platform, business workloads in `kube-system` (they should usually be moved) and any critical production workloads in `default` (they typically deserve dedicated namespaces).

        4. **Design and create the required namespaces**
           * Define the namespaces you need (from step 2), including labels/annotations for ownership and environment.
           * Create them:
             ```sh theme={null}
             kubectl create namespace prod-payments
             kubectl create namespace prod-frontend
             kubectl label namespace prod-payments env=prod team=payments
             kubectl label namespace prod-frontend env=prod team=frontend
             ```
           * Adjust names and labels to match your chosen scheme.

        5. **Plan and migrate workloads into appropriate namespaces**
           * For each workload identified in step 3, update its manifests to set `metadata.namespace` to the new target namespace and adjust any in-namespace references (ConfigMaps, Secrets, Services, RoleBindings, NetworkPolicies, etc.).
           * Apply the updated manifests:
             ```sh theme={null}
             kubectl apply -f updated-manifests/
             ```
           * Decommission the old objects from the previous namespace once the new ones are verified:
             ```sh theme={null}
             kubectl delete -f old-manifests/
             ```

        6. **Verify namespace-based boundaries are in place**
           * Confirm namespaces and workload placement:
             ```sh theme={null}
             kubectl get namespaces
             kubectl get all -n prod-payments
             kubectl get all -n prod-frontend
             ```
           * Ensure that the `default` namespace no longer hosts critical or multi-tenant workloads and that each major application/team/environment has a clearly defined namespace boundary.
      </Accordion>

      <Accordion title="Using kubectl">
        ```bash theme={null}
        # 1. List all namespaces and their age
        # Run on: any machine with kubectl access
        kubectl get namespaces -o wide
        ```

        **What to look for (possible problems)**

        * Only `default`, `kube-system`, `kube-public`, and `kube-node-lease` exist, but many applications/workloads are running → suggests everything is in `default` with no boundaries.
        * A single custom namespace (e.g., `prod`) containing *all* non-system workloads for different teams/environments → coarse boundary, little separation.

        ***

        ```bash theme={null}
        # 2. See which namespaces are actually used by workload objects
        kubectl get all --all-namespaces
        ```

        **What to look for (possible problems)**

        * Most or all Deployments/Pods/Services are in the `default` namespace.
        * Critical system-like components or third-party platforms (logging, monitoring, CI agents) running in `default` rather than a dedicated namespace.
        * Mixed environments (dev, test, prod) or mixed teams using the same namespace.

        ***

        ```bash theme={null}
        # 3. Show which namespaces have RoleBindings/ClusterRoleBindings
        kubectl get rolebindings,clusterrolebindings --all-namespaces
        ```

        **What to look for (possible problems)**

        * Broad, powerful RoleBindings (e.g., binding `cluster-admin` or wide-scoped roles) applied in a namespace that mixes unrelated workloads.
        * Lack of any RoleBindings in non-system namespaces when multiple teams share the cluster, suggesting no real separation of administrative duties.

        ***

        ```bash theme={null}
        # 4. Inspect a specific high-usage namespace (example: default)
        kubectl get all -n default
        kubectl get rolebindings -n default
        kubectl describe namespace default
        ```

        **What to look for (possible problems)**

        * Many unrelated applications, teams, or environments all running in `default`.
        * No labels/annotations that indicate intended ownership, environment, or purpose, making it hard to enforce policies and boundaries.

        ***

        ```bash theme={null}
        # 5. Correlate namespaces to application ownership using labels
        kubectl get namespaces --show-labels
        ```

        **What to look for (possible problems)**

        * No labeling strategy (e.g., no `team=...`, `env=...`, `app=...`), making it unlikely namespaces are being used as deliberate administrative boundaries.
        * One namespace with labels suggesting it serves multiple distinct environments or teams (e.g., `env=multi` or a generic `shared=true` for many unrelated workloads).

        ***

        Use the above outputs to answer, manually:

        * Are applications grouped into namespaces by environment, team, or function?
        * Are high-privilege permissions granted in namespaces that carry mixed or unrelated workloads?
        * Are there workloads still running in `default` that should be isolated into their own namespaces?
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        # Report namespace usage and isolation signals across the cluster.
        # Run on: any machine with kubectl access and current context set to target cluster.

        set -euo pipefail

        echo "== Cluster namespaces =="
        kubectl get namespaces -o wide

        echo
        echo "== Namespaces by label (team/app/environment) =="
        # Shows whether namespaces are tagged for ownership and purpose
        kubectl get ns \
          -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.labels.team:="(no-team)"}{"\t"}{.metadata.labels.app:="(no-app)"}{"\t"}{.metadata.labels.environment:="(no-env)"}{"\n"}' \
          | column -t

        echo
        echo "== Workloads per namespace (Deployments, StatefulSets, DaemonSets, Jobs, CronJobs, Pods) =="
        for ns in $(kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}'); do
          echo
          echo "--- Namespace: ${ns} ---"
          kubectl get deploy,sts,ds,job,cronjob,pod -n "${ns}" --ignore-not-found
        done

        echo
        echo "== ClusterRoles and ClusterRoleBindings (cluster-wide permissions) =="
        kubectl get clusterrole,clusterrolebinding -o wide

        echo
        echo "== RoleBindings that bind to ClusterRoles (potential cross-namespace power) =="
        kubectl get rolebinding --all-namespaces -o json \
          | jq -r '
            .items[]
            | .metadata.namespace as $ns
            | .metadata.name as $rb
            | .subjects[]? as $s
            | .roleRef
            | select(.kind=="ClusterRole")
            | [$ns, $rb, .name]
            | @tsv' 2>/dev/null \
          | awk 'BEGIN {print "NAMESPACE\tROLEBINDING\tCLUSTERROLE"} {print}' \
          | column -t

        echo
        echo "== ServiceAccounts used by Pods (by namespace) =="
        for ns in $(kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}'); do
          echo
          echo "--- Namespace: ${ns} ---"
          kubectl get pod -n "${ns}" -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.serviceAccountName}{"\n"}' 2>/dev/null \
            | awk 'BEGIN {print "POD\tSERVICEACCOUNT"} {print}' \
            | column -t || true
        done

        echo
        echo "== NetworkPolicies per namespace (is there traffic isolation?) =="
        for ns in $(kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}'); do
          echo
          echo "--- Namespace: ${ns} ---"
          kubectl get networkpolicy -n "${ns}" --ignore-not-found
        done

        echo
        echo "== Namespaces without any NetworkPolicy (potentially fully open) =="
        all_ns=$(kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}')
        np_ns=$(kubectl get networkpolicy --all-namespaces -o jsonpath='{range .items[*]}{.metadata.namespace}{"\n"}' | sort -u || true)
        echo "${all_ns}" | while read -r ns; do
          if ! echo "${np_ns}" | grep -qx "${ns}"; then
            echo "${ns}"
          fi
        done
        ```

        Explanation of what output may indicate a problem (to review manually):

        * `Cluster namespaces`:
          * Only `default`, `kube-system`, `kube-public`, `kube-node-lease` plus all workloads running in `default` may indicate missing administrative boundaries.
        * `Namespaces by label`:
          * Namespaces with `(no-team)` / `(no-env)` suggest lack of ownership and unclear separation.
        * `Workloads per namespace`:
          * Many unrelated applications co-located in the same namespace (especially `default`) indicate weak isolation.
        * `ClusterRoles and ClusterRoleBindings`:
          * Very broad cluster-wide roles (e.g., custom `*admin*` roles) bound to many subjects reduce the effectiveness of namespace boundaries.
        * `RoleBindings that bind to ClusterRoles`:
          * Numerous rolebindings to powerful ClusterRoles in many namespaces show that namespace boundaries are being bypassed by cluster-scoped permissions.
        * `ServiceAccounts used by Pods`:
          * Heavy reuse of the same high-privilege ServiceAccount across multiple namespaces/apps weakens separation.
        * `NetworkPolicies per namespace` and `Namespaces without any NetworkPolicy`:
          * Critical or multi-tenant namespaces with no NetworkPolicies likely have no network-level isolation between tenants or apps.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

* [https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/#viewing-namespaces](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/#viewing-namespaces)
