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 EKS
- 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 existing namespaces and workloads
- Run on: any machine with kubectl access
- Command:
kubectl get namespaceskubectl get all --all-namespaces
- Purpose: Understand what namespaces exist and which workloads currently run in each (especially in
default,kube-system, and other shared namespaces).
-
Identify workloads in inappropriate/shared namespaces
- Run on: any machine with kubectl access
- Commands (focus on
defaultand other “catch-all” namespaces):kubectl get all -n defaultkubectl get all -n kube-systemkubectl get all -A | grep -E 'test|dev|stage|prod' || true - Purpose: Detect application components that are mixed together without clear separation (e.g., multiple teams, environments, or apps sharing
default).
-
Define intended administrative boundaries
- Manual decision step (no command):
- Decide how you want to separate resources, for example:
- By environment:
dev,stage,prod - By team:
team-a,team-b - By application or domain:
payments,analytics, etc.
- By environment:
- Document a simple mapping: “Team/Environment/App → Namespace name”.
- Decide how you want to separate resources, for example:
- Manual decision step (no command):
-
Create or validate namespaces for each boundary
- Run on: any machine with kubectl access
- For each needed namespace
NAMESPACE_NAME, if it does not exist:kubectl get namespace NAMESPACE_NAME || kubectl create namespace NAMESPACE_NAME - Purpose: Ensure there is a dedicated namespace for each intended administrative boundary.
-
Plan and migrate workloads into appropriate namespaces
- Run on: any machine with kubectl access
- For each deployment/statefulset/etc. currently in a shared or inappropriate namespace:
- Export its manifest:
kubectl get deploy DEPLOYMENT_NAME -n CURRENT_NS -o yaml > DEPLOYMENT_NAME.yaml
- Edit the manifest file to set:
and adjust any namespace-scoped references (ConfigMaps, Secrets, ServiceAccounts, etc.).metadata:namespace: TARGET_NAMESPACE
- Apply it to the target namespace:
kubectl apply -f DEPLOYMENT_NAME.yaml
- Delete the old resource from the original namespace after confirming it’s running correctly in the new one:
kubectl delete deploy DEPLOYMENT_NAME -n CURRENT_NS
- Export its manifest:
- Repeat similarly for other resource kinds (Services, Jobs, CronJobs, ConfigMaps, Secrets, etc.), ensuring dependencies move together.
-
Verify namespace-based separation is in place
- Run on: any machine with kubectl access
- Commands:
kubectl get namespaceskubectl get all -A
- Check that:
- Application components are grouped in their intended dedicated namespaces.
- The
defaultnamespace and other shared namespaces no longer contain unrelated or multi-tenant workloads.
Using kubectl
# 1) List all namespaces and their age
# Run on: any machine with kubectl access
kubectl get namespaces -o wide
What to look for (potential problems):
- Only
default,kube-system,kube-public,kube-node-lease, and maybe one large custom namespace in use. - Many unrelated workloads (dev, test, prod, infra, third-party) all end up in
defaultor a single shared namespace.
# 2) See which namespaces your Pods and Services actually use
kubectl get pods,svc --all-namespaces
What to look for:
- Business apps, CI/CD tools, monitoring, logging, and system components all mixed in the same namespace (especially
default). - No clear separation by environment (e.g., dev/test/prod) or team/application.
# 3) Group workloads by namespace and label to understand boundaries
kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.metadata.labels}{"\n"}{end}' \
| sort
What to look for:
- Multiple teams or applications (seen in labels like
app=,team=,environment=) colocated in the same namespace without a clear reason. - Lack of consistent labeling that would indicate intentional grouping within namespaces.
# 4) Check access controls per namespace (role bindings)
kubectl get rolebindings,roles --all-namespaces
What to look for:
- Very broad permissions in shared namespaces (e.g., roles that can manage “everything”) used by multiple teams or apps.
- Critical infra or security-sensitive workloads in the same namespace as less-trusted or experimental workloads.
# 5) Inspect a specific namespace’s contents in more detail
NAMESPACE=default # change to the namespace you want to review
kubectl get all -n "$NAMESPACE" -o wide
kubectl get configmap,secret,ingress,networkpolicy -n "$NAMESPACE"
What to look for:
- “Catch‑all” namespaces with a mix of:
- Different applications
- Different environments (e.g., dev and prod together)
- Shared secrets or configmaps used by unrelated workloads
- Absence of
NetworkPolicyin a namespace that hosts mixed or sensitive workloads.
# 6) Review cluster-scoped bindings that might reduce the value of namespaces
kubectl get clusterrolebindings
What to look for:
- Users, groups, or service accounts with cluster‑wide admin permissions (
cluster-adminor similar) that make namespace separation less effective. - Service accounts that belong to “low trust” workloads being bound at cluster scope instead of namespace scope.
# 7) Optional: summarize objects per namespace (for a rough boundary picture)
kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' \
| while read ns; do
echo "=== Namespace: $ns ==="
kubectl get all -n "$ns" --no-headers 2>/dev/null | wc -l | awk '{print "Object count:", $1}'
done
What to look for:
- A very high object count in
defaultor a single namespace, with few or no other active namespaces. - Namespaces used only for one or two small workloads vs huge “everything” namespaces without a clear policy.
Automation
#!/usr/bin/env bash
# Report namespace usage and obvious multi-tenant risks
# Run on: any machine with kubectl access and current-context pointing to the target cluster
set -euo pipefail
echo "== Cluster-wide namespace summary =="
kubectl get ns --show-labels
echo
echo "== Namespaces with potentially sensitive or shared workloads (by common labels) =="
kubectl get pods -A -L 'app,app.kubernetes.io/name,app.kubernetes.io/part-of,tier,component' \
-o custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,APP:.metadata.labels.app,AKS_NAME:.metadata.labels.app\.kubernetes\.io/name,PART_OF:.metadata.labels.app\.kubernetes\.io/part-of,TIER:.metadata.labels.tier,COMPONENT:.metadata.labels.component' |
awk 'NR==1 || $1!="NAMESPACE" {print}'
echo
echo "== Workloads running in the default namespace (red flag in most clusters) =="
kubectl get all -n default
echo
echo "== ClusterRoles & ClusterRoleBindings referencing subjects in shared namespaces =="
# This helps spot shared-admin patterns where multiple teams share a namespace
kubectl get clusterrole,clusterrolebinding -o yaml | awk '
$1=="kind:"{k=$2}
$1=="metadata:"{inm=1; next}
inm && $1=="name:"{n=$2; gsub(/"/,"",n); inm=0}
$1=="subjects:"{ins=1; next}
ins && $1=="-"{ns=""; kind=""; name=""}
ins && $1=="kind:"{kind=$2}
ins && $1=="name:"{name=$2}
ins && $1=="namespace:"{ns=$2}
ins && $1=="-"{}
ins && $1=="roleRef:"{ins=0}
ins && ns!=""{
gsub(/"/,"",ns); gsub(/"/,"",kind); gsub(/"/,"",name)
print k"\t"n"\t"kind"\t"name"\t"ns
}' | sort -u | column -t || true
echo
echo "== List of workloads per namespace (helps see shared vs isolated usage) =="
kubectl get deploy,sts,ds,job,cronjob -A -o custom-columns='KIND:.kind,NAMESPACE:.metadata.namespace,NAME:.metadata.name' | sort
echo
echo "== ServiceAccounts used by pods per namespace (for privilege / tenancy review) =="
kubectl get pods -A -o custom-columns='NAMESPACE:.metadata.namespace,POD:.metadata.name,SA:.spec.serviceAccountName' | sort
echo
echo "== NetworkPolicies per namespace (namespaces without any are more exposed) =="
kubectl get networkpolicy -A || echo "No NetworkPolicies found in cluster"
echo
echo "== Namespaces without any workloads (candidates for cleanup or future isolation) =="
all_ns=$(kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}')
used_ns=$(kubectl get pods,deploy,sts,ds,job,cronjob -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\n"}{end}' | sort -u)
echo "${all_ns}" | sort -u | grep -v -F -x -f <(echo "${used_ns}" | sort -u) || true
echo
echo "== Guidance: How to interpret this output =="
cat <<'EOF'
Potential problems to look for manually:
1) Workloads in "default" namespace:
- Any application pods, deployments, services, or jobs in the "default" namespace usually
indicate missing administrative boundaries. Each logical app/team/tenant should normally
have its own namespace.
2) Many unrelated apps in the same namespace:
- In the workloads-per-namespace listing, if a namespace contains many unrelated apps
(different teams, tenants, or environments like dev/test/prod together), that namespace
likely lacks clear administrative separation.
3) Shared namespaces for different privilege levels:
- In the ServiceAccounts-per-namespace section, if highly privileged SAs and unprivileged
SAs are used in the same namespace, consider splitting them into separate namespaces with
different RBAC and NetworkPolicies.
4) ClusterRoleBindings referencing many subjects in one namespace:
- If the ClusterRole/ClusterRoleBinding section shows many human or app identities from
one shared namespace getting broad cluster-wide privileges, that is an indicator that
per-team or per-application namespaces are not being used as an administrative boundary.
5) Namespaces without NetworkPolicies:
- Namespaces holding sensitive or multi-tenant workloads but lacking NetworkPolicies
have weaker isolation. This is not strictly an RBAC boundary but is part of effective
namespace-based isolation.
6) Unused or empty namespaces:
- Namespaces with no workloads may be legacy or unused; decide whether to remove them or
repurpose them explicitly so that namespace usage remains intentional and auditable.
This script only reports the current state. You must decide, per environment and business
requirements, where new namespaces are needed to separate teams, tenants, environments, or
privilege levels, and then refactor workloads and RBAC accordingly.
EOF