Create Administrative Boundaries Between Resources Using
More Info:
Namespaces provide administrative and security boundaries between sets of resources. Create dedicated namespaces to segregate workloads and apply scoped RBAC controls.
Risk Level
Low
Address
Security
Compliance Standards
- CIS EKS
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
Inventory current namespaces and their workloads
- Run on: any machine with kubectl access
- Command:
kubectl get namespaceskubectl get all --all-namespaces
- Review whether business-critical, shared, and system workloads are clearly separated (e.g.,
kube-system,kube-public, provider-managed namespaces vs. your own application namespaces).
-
Identify workloads running in default or shared namespaces
- Run on: any machine with kubectl access
- Command:
kubectl get all -n defaultkubectl get all -n kube-systemkubectl get all -n kube-publickubectl get all -n kube-node-lease
- Determine which of these are your application workloads (not system or add-ons) and whether they should be isolated into dedicated namespaces (e.g., per team, environment, or application).
-
Design a namespace strategy and plan moves
- Decide target namespaces (e.g.,
team-a-prod,team-a-dev,shared-tools) and which workloads must be isolated for security, access control, or quota reasons. - For each workload in an inappropriate namespace, plan:
- Target namespace name
- Matching RBAC scope (ServiceAccounts, Roles, RoleBindings)
- Any NetworkPolicies or ResourceQuotas/LimitRanges to apply.
- Decide target namespaces (e.g.,
-
Create or update namespaces and associated policies
- Run on: any machine with kubectl access
- Command (example – adjust names and labels to your design):
kubectl create namespace team-a-prodkubectl label namespace team-a-prod env=prod team=team-a --overwrite
- Optionally add baseline policies per namespace, for example:
# Example Role scoped to the namespacecat <<'EOF' | kubectl apply -f -apiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata:name: app-readonlynamespace: team-a-prodrules:- apiGroups: [""]resources: ["pods","services","configmaps","secrets"]verbs: ["get","list","watch"]EOF
-
Migrate workloads into their dedicated namespaces
- Run on: any machine with kubectl access
- Export and re-apply manifests into the new namespaces (update
metadata.namespace):# Example: export a deployment currently in default namespacekubectl get deploy my-app -n default -o yaml > my-app.yamlsed -i 's/namespace: default/namespace: team-a-prod/' my-app.yamlkubectl apply -f my-app.yamlkubectl delete deploy my-app -n default - Ensure related objects (Services, ConfigMaps, Secrets, ServiceAccounts, Roles/RoleBindings, NetworkPolicies) are also created in the target namespace and references are updated.
-
Verify namespace boundaries and workload placement
- Run on: any machine with kubectl access
- Commands:
kubectl get namespaces --show-labelskubectl get all --all-namespaces
- Confirm that:
- Non-system workloads are no longer running in
defaultor system namespaces unless explicitly intended. - Workloads are grouped into appropriate dedicated namespaces that align with your administrative and security boundaries.
- Non-system workloads are no longer running in
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 (possible issues):
- Only
default,kube-system,kube-public, andkube-node-leaseexist, but many workloads run indefault. - Very old
defaultnamespace with many unrelated workloads suggests no logical separation.
# 2. See which namespaces workloads are running in (workloads only)
kubectl get deploy,sts,ds,job,cronjob,svc,ingress --all-namespaces
What to look for:
- Multiple unrelated applications (e.g., payments, logging, demo, staging, prod) all in the same namespace (often
default). - Shared namespace between system components and business apps.
# 3. List all pods with labels to infer logical groupings
kubectl get pods --all-namespaces --show-labels
What to look for:
- Labels like
app=payments,env=prod,team=ml, etc., all in one namespace instead of being grouped into separate namespaces by environment, team, or function. - No clear correlation between labels and namespace boundaries.
# 4. Inspect RBAC bindings and where they apply
kubectl get rolebinding,clusterrolebinding --all-namespaces -o wide
What to look for:
- Overuse of
ClusterRoleBindinggranting broad roles (e.g.,cluster-admin) instead of namespace-scopedRoleBinding. - Critical or sensitive workloads in namespaces that share wide RBAC bindings with unrelated workloads.
# 5. For a specific namespace, inspect its RBAC in detail
NAMESPACE=default # replace with namespace under review
kubectl get role,rolebinding -n "${NAMESPACE}" -o yaml
kubectl get pods,svc,deploy,sts,ds,job,cronjob,ingress -n "${NAMESPACE}" -o yaml
What to look for:
- A namespace mixing:
- different environments (dev/test/prod),
- different business domains (payments, analytics, logging),
- different teams or tenants, all with similar RBAC permissions.
- Lack of any dedicated namespaces for components that clearly should be isolated (e.g., security tools, logging, monitoring, prod workloads).
# 6. Identify workloads still running in the default namespace
kubectl get all -n default
What to look for:
- Long-lived application workloads or critical services in
defaultinstead of a dedicated namespace (e.g.,payments-prod,team-a-dev,logging,monitoring).
# 7. (Optional) Show namespace labels/annotations that may indicate intended boundaries
kubectl get ns -o yaml
What to look for:
- Important logical groups (tenant, team, env, data-sensitivity) present only as labels but not used to define actual namespace boundaries (e.g., multiple teams or envs mixed in one namespace despite labels suggesting separation is desired).
If these commands show that unrelated teams, environments, or sensitivity levels are mixed in the same namespaces, or that most workloads live in default, the cluster likely lacks appropriate administrative boundaries and requires a human-designed namespace model and migration plan.
Automation
#!/usr/bin/env bash
# Assess namespace usage to review administrative boundaries
# Run on: any machine with kubectl access and cluster-wide read permissions
set -euo pipefail
echo "=== 1) List all namespaces with age and labels (for grouping/ownership) ==="
kubectl get ns --show-labels -o wide
echo
echo "=== 2) Workloads per namespace (Pods, Deployments, StatefulSets, DaemonSets, Jobs, CronJobs) ==="
for ns in $(kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}'); do
echo
echo "----- Namespace: ${ns} -----"
kubectl get pods,deploy,sts,ds,job,cronjob -n "${ns}" 2>/dev/null || echo " (no core workloads or no permission)"
done
echo
echo "=== 3) ServiceAccounts and their usage per namespace ==="
for ns in $(kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}'); do
echo
echo "----- Namespace: ${ns} -----"
echo "- ServiceAccounts:"
kubectl get sa -n "${ns}" -o wide 2>/dev/null || echo " (no serviceaccounts or no permission)"
echo
echo "- Pods and their ServiceAccounts:"
kubectl get pods -n "${ns}" -o custom-columns='NAMESPACE:.metadata.namespace,POD:.metadata.name,SA:.spec.serviceAccountName' 2>/dev/null \
|| echo " (no pods or no permission)"
done
echo
echo "=== 4) Cluster-wide RBAC resources referencing namespaces ==="
echo
echo "- ClusterRoles (cluster-scoped permissions):"
kubectl get clusterrole
echo
echo "- ClusterRoleBindings (who has cluster-scoped permissions):"
kubectl get clusterrolebinding -o wide
echo
echo "=== 5) Namespaced RBAC per namespace ==="
for ns in $(kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}'); do
echo
echo "----- Namespace: ${ns} -----"
echo "- Roles:"
kubectl get role -n "${ns}" -o wide 2>/dev/null || echo " (no Roles or no permission)"
echo
echo "- RoleBindings:"
kubectl get rolebinding -n "${ns}" -o wide 2>/dev/null || echo " (no RoleBindings or no permission)"
done
echo
echo "=== 6) High-privilege bindings (cluster-admin or similar) by subject and namespace ==="
# Cluster-admin via ClusterRoleBinding
echo
echo "- ClusterRoleBindings that grant 'cluster-admin':"
kubectl get clusterrolebinding -o json \
| jq -r '
.items[]
| select(.roleRef.kind=="ClusterRole" and .roleRef.name=="cluster-admin")
| "Binding: \(.metadata.name)\n Subjects:\n" +
( .subjects[]?
| " - kind: \(.kind), name: \(.name), namespace: \(.namespace // "-")"
)
' || echo "jq not installed; skip detailed view (install jq to see more detail)"
# Detect RoleBindings that refer to high-privilege ClusterRoles (by name pattern)
echo
echo "- RoleBindings that reference ClusterRoles (potential cross-namespace high privilege):"
kubectl get rolebinding --all-namespaces -o json \
| jq -r '
.items[]
| select(.roleRef.kind=="ClusterRole")
| "Namespace: \(.metadata.namespace), RoleBinding: \(.metadata.name), ClusterRoleRef: \(.roleRef.name)"
' || echo "jq not installed; skip this check"
echo
echo "=== 7) Pods running in core / shared namespaces (kube-system, default, kube-public) ==="
for ns in default kube-system kube-public; do
echo
echo "----- Namespace: ${ns} -----"
kubectl get pods -n "${ns}" -o wide 2>/dev/null || echo " (namespace not found or no pods)"
done
echo
echo "=== 8) Summary hint (manual review required) ==="
cat <<'EOF'
Manual review guidance (what output indicates a potential problem):
1) From section 1:
- Workloads concentrated heavily in 'default' or other shared/core namespaces
instead of being grouped into dedicated application or team namespaces.
- Lack of meaningful labels (e.g., missing team/app/env/owner labels) that would
indicate clear administrative ownership of namespaces.
2) From section 2:
- Multiple unrelated applications or teams sharing the same namespace.
- System components and tenant workloads mixed in the same namespace.
3) From section 3:
- Many pods in a namespace sharing a single broad ServiceAccount instead of
more granular ServiceAccounts per application or function.
4) From sections 4 and 6:
- Frequent or broad use of 'cluster-admin' via ClusterRoleBindings (especially
bound to users/groups that should be limited to specific namespaces).
- RoleBindings that reference ClusterRoles across namespaces, implying
potentially unnecessary cluster-wide privileges for namespace-scoped users.
5) From section 5:
- Namespaces with workloads but no namespace-scoped Roles/RoleBindings,
relying solely on cluster-scoped RBAC (weakens namespace boundaries).
6) From section 7:
- Tenant or application workloads running in 'kube-system', 'kube-public',
or 'default' instead of dedicated namespaces.
Use these findings to decide where to:
- Introduce new namespaces to separate teams, environments, or applications.
- Tighten RBAC so users and ServiceAccounts have access only to their namespaces.
EOF