Create Administrative Boundaries Between Resources Using
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 OKE
- 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
- Remediation
Remediation
Manual Steps
-
Inventory current namespaces and their workloads
- On any machine with kubectl access:
kubectl get namespaceskubectl get all --all-namespaces
- Review which applications, environments (dev/test/prod), or teams are sharing the same namespace (especially
default).
- On any machine with kubectl access:
-
Identify applications using shared or inappropriate namespaces
- List objects in the
defaultnamespace (and any other obviously shared namespaces):kubectl get deploy,sts,ds,svc,ingress,cm,secret,sa,job,cronjob -n default - For each listed object, decide which logical boundary it belongs to (e.g., team, app, environment, or project).
- List objects in the
-
Define the desired namespace model and create namespaces
- Decide on a small, clear set of namespaces that reflect administrative boundaries (e.g.,
team-a-prod,team-a-dev,payments,logging, etc.). - Create them:
kubectl create namespace team-a-prodkubectl create namespace team-a-dev# Add more as needed, matching your chosen model
- Decide on a small, clear set of namespaces that reflect administrative boundaries (e.g.,
-
Plan and migrate workloads into appropriate namespaces
- Export existing manifests from shared namespaces for editing:
kubectl get deploy,sts,ds,svc,ingress,cm,secret,sa,job,cronjob -n default -o yaml > /tmp/default-workloads.yaml
- Edit
/tmp/default-workloads.yamland, for each object to be moved, setmetadata.namespaceto the appropriate target namespace. - Apply the updated manifests:
kubectl apply -f /tmp/default-workloads.yaml
- After confirming successful creation in the new namespace, delete the old instances from
default:kubectl delete -f /tmp/default-workloads.yaml -n default --ignore-not-found
- Export existing manifests from shared namespaces for editing:
-
Enforce use of namespaces for future deployments
- Optionally create a simple namespace usage policy by documenting which namespace each team/app must use.
- If you use GitOps or CI/CD, ensure manifests and Helm charts specify
metadata.namespace(or Helm--namespaceflag) rather than relying ondefault.
-
Verify namespace-based separation
- On any machine with kubectl access, confirm that application objects now reside in non-default, purpose-specific namespaces and that
defaultis mostly empty or only contains intentional resources:kubectl get all --all-namespaceskubectl get all -n default - Confirm that applications belonging to different administrative boundaries are no longer sharing the same namespace unless explicitly intended.
- On any machine with kubectl access, confirm that application objects now reside in non-default, purpose-specific namespaces and that
Using kubectl
Using kubectl
Run these commands from any machine with kubectl access.
- List all namespaces and basic metadata
kubectl get namespaces -o wide
Review points / potential problems:
- Only
default,kube-system, and a small number of clearly named namespaces exist, but many unrelated apps are deployed (see next steps) → suggests poor separation. - Business‑critical, dev/test, and third‑party workloads appear to share the same namespace (often
defaultor a single custom namespace).
- See what runs in each namespace
kubectl get pods -A -o wide
Focus on columns NAMESPACE and NAME:
- Many unrelated applications or teams sharing one namespace, especially
default, indicates weak administrative boundaries. - System and platform components (ingress, monitoring, CI runners, internal apps) all mixed in one or two namespaces is a red flag.
- Check which namespaces are actually used for application workloads
kubectl get deploy,sts,ds,job,cronjob -A -o wide
Look for:
- Application controllers (Deployments, StatefulSets, etc.) living in
defaultalongside core platform or test workloads. - Lack of clear grouping (e.g., no separation like
prod-*,dev-*,team-*,system-*); this makes RBAC scoping and blast-radius control hard.
- Inspect namespace labels/annotations (used for policy/RBAC scoping)
kubectl get ns --show-labels
kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.annotations}{"\n"}{end}'
Potential issues:
- Critical namespaces lack labels that would distinguish environment, owner, or sensitivity (e.g., no
env=prod,owner=team-a,tier=platform), making it hard to target RBAC and policies. - No clear way to identify which namespace belongs to which team or environment.
- Check if the
defaultnamespace is overloaded
kubectl get all -n default
Indicates a problem when:
- Many independent apps, batch jobs, and third‑party tools are all in
defaultrather than structured namespaces. - Production workloads reside in
defaultalongside experimental or transient workloads.
- Review role bindings per namespace (to understand intended boundaries)
kubectl get rolebinding,clusterrolebinding -A
Use this for context:
- If a few broad
ClusterRoleBindings grant access cluster‑wide, and there are no namespace‑scopedRoleBindings tailored to specific namespaces, then namespaces are not being used effectively as administrative boundaries. - If multiple teams share the same namespace and are all granted access via the same bindings, you likely need more granular namespace separation.
These commands only expose how namespaces are currently used; a human must decide if namespaces should be split, renamed, or reorganized to create appropriate administrative boundaries.
Automation
#!/usr/bin/env bash
# Report namespace usage and potential isolation issues
# Run on: any machine with kubectl access
# Usage: ./namespace-boundaries-report.sh
set -euo pipefail
echo "=== 1) Namespaces and labels ==="
kubectl get ns --show-labels
echo
echo "=== 2) Workloads per namespace (Deployments, StatefulSets, DaemonSets, Jobs, CronJobs) ==="
kubectl get deploy,sts,ds,job,cronjob -A -o wide || true
echo
echo "=== 3) Pods per namespace (including owning controller) ==="
kubectl get pods -A -o custom-columns=NS:.metadata.namespace,NAME:.metadata.name,PHASE:.status.phase,OWNER:.metadata.ownerReferences[0].kind,OWNER_NAME:.metadata.ownerReferences[0].name --sort-by=.metadata.namespace
echo
echo "=== 4) ClusterRoles and ClusterRoleBindings (cross-namespace permissions) ==="
echo "--- ClusterRoles ---"
kubectl get clusterrole -o wide
echo
echo "--- ClusterRoleBindings ---"
kubectl get clusterrolebinding -o custom-columns=NAME:.metadata.name,SA_SUBJECT_NS:.subjects[?(@.kind==\"ServiceAccount\")].namespace,SA_SUBJECT_NAME:.subjects[?(@.kind==\"ServiceAccount\")].name,ROLE:.roleRef.name
echo
echo "=== 5) RoleBindings (namespaced RBAC, who can affect what) ==="
kubectl get rolebinding -A -o custom-columns=NS:.metadata.namespace,NAME:.metadata.name,SUBJECT_KIND:.subjects[0].kind,SUBJECT_NS:.subjects[0].namespace,SUBJECT_NAME:.subjects[0].name,ROLE_KIND:.roleRef.kind,ROLE_NAME:.roleRef.name
echo
echo "=== 6) ServiceAccounts per namespace ==="
kubectl get sa -A -o custom-columns=NS:.metadata.namespace,NAME:.metadata.name --sort-by=.metadata.namespace
echo
echo "=== 7) NetworkPolicies per namespace (traffic isolation) ==="
kubectl get networkpolicy -A -o custom-columns=NS:.metadata.namespace,NAME:.metadata.name,POLICY_TYPES:.spec.policyTypes --sort-by=.metadata.namespace || echo "No NetworkPolicies found"
echo
echo "=== 8) Namespaces with no NetworkPolicies defined ==="
# Namespaces with zero NetworkPolicies – often indicate no traffic isolation
ns_all=$(kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}')
ns_np=$(kubectl get networkpolicy -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\n"}{end}' 2>/dev/null | sort -u || true)
echo "Namespaces with NO NetworkPolicies:"
comm -23 <(printf "%s\n" $ns_all | sort -u) <(printf "%s\n" $ns_np | sort -u)
echo
echo "=== 9) Namespaces with mixed application labels (potentially shared by multiple teams/apps) ==="
# Heuristic: list distinct 'app' labels per namespace
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{" "}{.metadata.labels.app}{"\n"}{end}' \
| awk '$2!="" {print}' \
| sort -u \
| awk '{count[$1]++} END {for (ns in count) if (count[ns]>1) print ns, "has", count[ns], "distinct app labels"}' \
| sort
echo
echo "=== 10) System vs user namespaces (for manual review) ==="
echo "Common system namespaces (should generally be separate from user workloads):"
echo " - kube-system"
echo " - kube-public"
echo " - kube-node-lease"
echo " - default (often misused for apps)"
echo
kubectl get pods -n default -o wide || echo "No pods in 'default' namespace"
echo
echo "=== 11) Summary hints for manual review ==="
cat <<'EOF'
Review guidance (manual, not automated pass/fail):
1) Namespaces and labels:
- Potential issue if:
* Most or all workloads run in 'default'.
* No clear team/app labels on namespaces.
2) Workloads/Pods per namespace:
- Potential issue if:
* Multiple unrelated applications share a single namespace with no clear reason.
* System and user workloads are mixed in the same namespace.
3) RBAC (ClusterRole/ClusterRoleBinding/RoleBinding):
- Potential issue if:
* ClusterRoleBindings grant broad privileges (e.g. cluster-admin) to service accounts used across many namespaces.
* Service accounts in one team/namespace can administer resources in others without clear justification.
4) NetworkPolicies:
- Potential issue if:
* Business-critical namespaces have no NetworkPolicies (no traffic isolation).
* One namespace is clearly used as a "shared" zone for many unrelated apps with no isolation.
5) Default namespace:
- Potential issue if:
* User applications are routinely deployed to 'default' instead of dedicated namespaces.
Use this report to decide:
- Which teams/apps should be separated into their own namespaces.
- Where RBAC and NetworkPolicies need tightening to respect those boundaries.
EOF