Create Administrative Boundaries Between Resources Using
More Info:
Namespaces provide administrative and security boundaries between groups of resources. Use them to segregate workloads.
Risk Level
Low
Address
Security
Compliance Standards
- CIS Kubernetes
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
Inventory current namespaces and workloads
- Run on: any machine with kubectl access
- Command:
kubectl get namespaceskubectl get all --all-namespaces
- Purpose: Identify what namespaces exist and which Pods/Services/Deployments are concentrated in
defaultor other shared namespaces.
-
Identify security/administrative domains that should be isolated
- Run on: any machine with kubectl access
- Commands (to help group by label/owner):
kubectl get pods --all-namespaces -o wide --show-labelskubectl get deployments --all-namespaces -o wide --show-labels
- Review points:
- Which teams, environments (dev/test/stage/prod), or applications share a namespace?
- Which workloads have different data sensitivity, access requirements, or change-control rules but share a namespace?
-
Decide and document a namespace model
- No command; design decision.
- Suggested patterns to evaluate:
- Per-environment (e.g.,
dev,staging,prod) - Per-team (e.g.,
team-a,team-b) - Per-application or domain (e.g.,
payments,analytics)
- Per-environment (e.g.,
- Ensure future objects will be created in these namespaces (CI/CD changes, Helm values, etc.).
-
Create required namespaces
- Run on: any machine with kubectl access
- Commands (example – adjust names to your model):
kubectl create namespace devkubectl create namespace stagingkubectl create namespace prod
- For GitOps/manifest-driven clusters, create YAML instead and apply via your pipeline:
Apply:apiVersion: v1kind: Namespacemetadata:name: dev---apiVersion: v1kind: Namespacemetadata:name: staging---apiVersion: v1kind: Namespacemetadata:name: prodkubectl apply -f namespaces.yaml
-
Plan and migrate workloads out of shared/default namespaces
- Run on: any machine with kubectl access
- Evidence to gather for each namespace you intend to clean up:
# Workloads in default and any other shared namespacekubectl get all -n defaultkubectl get all -n <shared-namespace># ConfigMaps, Secrets, RBAC bindings that may need moving or duplicatingkubectl get configmaps,secrets,serviceaccounts,roles,rolebindings -n defaultkubectl get configmaps,secrets,serviceaccounts,roles,rolebindings -n <shared-namespace>
- For each application, update its manifests/Helm values/CI to set
metadata.namespace: <target-namespace>, then re-deploy there. Clean up old objects after validating functionality.
-
Verify namespace-based segregation is in place
- Run on: any machine with kubectl access
- Commands:
kubectl get namespaceskubectl get all --all-namespaces
- Review points:
- Sensitive or production workloads run in dedicated namespaces, not
default. - Distinct teams/environments/applications have their own namespaces according to your model.
- New deployments (from CI/CD) are landing in the intended namespaces, not in
default.
- Sensitive or production workloads run in dedicated namespaces, not
Using kubectl
Using kubectl
1. List all namespaces and look for over‑concentration of workloads
Run on: any machine with kubectl access
kubectl get namespaces
Review guidance (possible problems):
- Everything (system and all apps) is running in just
default(and maybekube-*system namespaces). - Business‑critical, dev, and test workloads are all in the same non‑system namespace.
2. See what’s running in the default namespace
Run on: any machine with kubectl access
kubectl get all -n default
Review guidance (possible problems):
- Application workloads for multiple teams or environments are all in
default. - Sensitive workloads (e.g., production databases) run in
defaultinstead of a dedicated namespace.
3. Get a cross‑namespace view of workloads
Run on: any machine with kubectl access
kubectl get pods --all-namespaces
Review guidance (possible problems):
- A small number of namespaces containing a large mix of unrelated workloads.
- No clear separation by environment (e.g., prod/stage/dev) or by tenant/team when that is a requirement.
To go deeper for specific kinds:
kubectl get deploy,sts,ds,job,cronjob --all-namespaces
Look for:
- Deployments/StatefulSets/DaemonSets from multiple teams or tenants sharing one namespace without justification.
4. Inspect labeling/ownership patterns
Run on: any machine with kubectl access
kubectl get ns --show-labels
Review guidance (possible problems):
- No labels to indicate environment (
env=prod|stage|dev) or owner/team when such separation is expected. - Namespaces used as a “dumping ground” with unclear purpose.
5. Spot potential multi‑tenant or shared admin issues
Run on: any machine with kubectl access
Check for role bindings that span many subjects in a shared namespace:
kubectl get rolebindings,clusterrolebindings -A
Review guidance (possible problems):
- A single shared namespace where many different user groups are granted broad access, instead of each having their own namespace.
- Cluster‑wide roles used where namespace‑scoped roles and separate namespaces would provide better isolation.
If these reviews show that unrelated workloads, tenants, or environments are co‑located in the same namespace without a clear reason, that indicates missing or insufficient administrative boundaries and may require a namespace design change (performed via manifests/kubectl and aligned with your org’s requirements).
Automation
#!/usr/bin/env bash
#
# cis-5.6.1-namespaces-inventory.sh
#
# Purpose:
# Provide a cluster-wide view of namespace usage so you can manually review
# whether administrative boundaries are being used appropriately.
#
# Requirements:
# - Run on any machine with kubectl configured and RBAC rights to list
# namespaces, pods, deployments, statefulsets, daemonsets, jobs, cronjobs.
# - kubectl v1.20+ recommended.
set -euo pipefail
echo "=== [1/5] Namespaces and basic metadata ==="
kubectl get ns -o wide
echo
echo "=== [2/5] Namespaces with counts of core workload objects ==="
# For each namespace, show counts of Pods, Deployments, StatefulSets,
# DaemonSets, Jobs, and CronJobs.
kubectl get ns -o json \
| jq -r '
.items[]
| .metadata.name as $ns
| {
namespace: $ns,
pods: (try (.pods // 0) catch 0),
deploys: (try (.deploys // 0) catch 0),
ssets: (try (.ssets // 0) catch 0),
dsets: (try (.dsets // 0) catch 0),
jobs: (try (.jobs // 0) catch 0),
cjobs: (try (.cjobs // 0) catch 0)
}
' 2>/dev/null || {
# Fallback without jq pre-processing if jq is unavailable
echo "jq not found or failed; using slower kubectl-based fallback..." >&2
for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
pods=$(kubectl get pods -n "$ns" --no-headers 2>/dev/null | wc -l || echo 0)
deploys=$(kubectl get deploy -n "$ns" --no-headers 2>/dev/null | wc -l || echo 0)
ssets=$(kubectl get sts -n "$ns" --no-headers 2>/dev/null | wc -l || echo 0)
dsets=$(kubectl get ds -n "$ns" --no-headers 2>/dev/null | wc -l || echo 0)
jobs=$(kubectl get job -n "$ns" --no-headers 2>/dev/null | wc -l || echo 0)
cjobs=$(kubectl get cronjob -n "$ns" --no-headers 2>/dev/null | wc -l || echo 0)
printf "%-25s pods=%-4s deploys=%-4s sts=%-4s ds=%-4s jobs=%-4s cjobs=%-4s\n" \
"$ns" "$pods" "$deploys" "$ssets" "$dsets" "$jobs" "$cjobs"
done
exit 0
'
echo
echo "=== [3/5] Workloads still running in the default namespace ==="
kubectl get all -n default
echo
echo "=== [4/5] Cluster-scoped workloads (no namespace boundary) ==="
echo "# Cluster-scoped controllers:"
kubectl get clusterrole,clusterrolebinding,crd,storageclass -A
echo
echo "=== [5/5] Heuristic: namespaces that may be mixing unrelated workloads ==="
echo "# This highlights namespaces with many different apps (based on labels)."
echo "# Review namespaces with many distinct app labels for possible overloading."
kubectl get pods -A -o json \
| jq -r '
.items[]
| {
ns: .metadata.namespace,
app: (
.metadata.labels.app
// .metadata.labels."app.kubernetes.io/name"
// "UNLABELED"
)
}
| "\(.ns) \(.app)"
' 2>/dev/null | sort | uniq -c | sort -k2,2 -k1,1nr
echo
echo "=== Interpretation guidance ==="
cat <<'EOF'
Use this output to manually decide if you are creating appropriate administrative
boundaries with namespaces:
- Potential problems include:
- Most or all application workloads running in the 'default' namespace.
- A single namespace containing many unrelated applications/teams
(look at the heuristic app-label listing).
- Lack of clear separation between environments (e.g., dev/test/prod all in
one namespace).
- Sensitive or privileged workloads sharing namespaces with general workloads.
This script does NOT change the cluster; it only reports current state for review.
Creating or refactoring namespaces and moving workloads must be planned and
performed manually (updating manifests, Helm values, or other IaC).
EOF