Skip to main content

The Default Namespace Should Not Be Used

More Info:

Placing resources in the default namespace prevents proper segregation and access control. Use purpose-specific namespaces instead.

Risk Level

Low

Address

Security

Compliance Standards

  • CIS Kubernetes

Triage and Remediation

Remediation

Manual Steps
  1. List all workloads and core resources in the default namespace

    • Run on: any machine with kubectl access
    kubectl get all,cm,secret,sa,role,rolebinding,networkpolicy -n default
    kubectl get ingress -n default
    kubectl get pvc -n default

    Review whether each object is intentionally in default or just there by habit/convenience.

  2. Identify ownership and required segregation for each object

    • Run on: any machine with kubectl access
    kubectl get deploy,sts,ds,job,cronjob -n default -o wide
    kubectl get svc -n default -o wide
    kubectl get sa,role,rolebinding -n default -o yaml

    For each application or component, decide:

    • Which team/tenant owns it.
    • What security or lifecycle boundaries it needs.
    • What namespace(s) should exist instead (e.g., team-a-prod, shared-infra, monitoring).
  3. Create or confirm purpose-specific namespaces

    • Run on: any machine with kubectl access
      For each logical grouping you identified:
    kubectl create namespace team-a-prod
    kubectl create namespace shared-infra

    (Adjust names as decided; skip if already present: kubectl get ns to check.)
    Optionally add labels/annotations to express purpose/ownership:

    kubectl label namespace team-a-prod owner=team-a env=prod --overwrite
  4. Plan and migrate resources out of default to their target namespaces

    • Run on: any machine with kubectl access
      For each object to move:
    1. Export its manifest:
      kubectl get deployment my-app -n default -o yaml > my-app.yaml
    2. Edit the file:
      • Change metadata.namespace: default to the target namespace.
      • Update references (serviceAccountName, ConfigMap/Secret names, RoleBindings, NetworkPolicies) if they change.
    3. Apply to the new namespace and delete from default:
      kubectl apply -f my-app.yaml
      kubectl delete deployment my-app -n default

    Repeat this pattern for Services, ConfigMaps, Secrets, ServiceAccounts, Roles/RoleBindings, NetworkPolicies, Jobs/CronJobs, PVCs (being careful with data and StorageClass constraints).

  5. Harden RBAC and defaults to discourage future use of default

    • Run on: any machine with kubectl access
      Consider:
    • Removing broad bindings in default:
      kubectl get rolebinding,clusterrolebinding -A | grep default
      kubectl delete rolebinding <name> -n default
    • Creating least-privilege RoleBindings only in intended namespaces and ensuring users’ kubeconfigs specify a non-default namespace:
      kubectl config set-context $(kubectl config current-context) --namespace=team-a-prod
  6. Verify that default is no longer used for application resources

    • Run on: any machine with kubectl access
    kubectl get all,cm,secret,sa,role,rolebinding,networkpolicy,ingress,pvc -n default

    Confirm that:

    • Only objects you explicitly want there remain (often just system bootstrap artifacts, if any).
    • All application, team, or environment-specific resources have been moved to purpose-specific namespaces.
Using kubectl

Using kubectl

Run these commands from any machine with kubectl access.

1. List all namespaces and spot obvious mis-use of default

kubectl get ns

What to look for (potential problems):

  • Only default, kube-system, and other system namespaces exist, and no clearly purpose-specific namespaces for apps or teams.
  • Application names suggest they should have their own namespaces, but do not (e.g., you see payments, frontend as Deployments in default later).

2. See what is currently running in the default namespace

kubectl get all -n default

If you also use other workload types:

kubectl get deploy,sts,ds,job,cronjob,svc,ingress,cm,secret -n default

What to look for (potential problems):

  • Business applications (e.g., orders-api, payments-db, frontend) running in default.
  • Shared infrastructure components (e.g., logging, monitoring, CI/CD agents) running in default.
  • Any long-lived workloads or services that clearly belong to a specific team, environment (dev/test/prod), or function, but are not in a dedicated namespace.

Using default for:

  • Only temporary/manual testing objects, clearly named as such and cleaned up regularly, is usually acceptable.
  • Anything production-like is a concern.

3. Check RBAC bindings that reference the default namespace

kubectl get rolebindings,roles -n default

What to look for (potential problems):

  • Broad roles (e.g., with * verbs or many resources) attached in default, especially if:
    • default contains many or critical workloads.
    • ServiceAccounts in default are used by multiple apps/teams.

This indicates access control is being applied to a “catch-all” namespace instead of segregated namespaces.

4. Check what is using the default ServiceAccount

kubectl get pods -n default -o custom-columns='POD:.metadata.name,SA:.spec.serviceAccountName'

What to look for (potential problems):

  • Many or critical pods using the implicit default ServiceAccount (<none> or default in the output), especially if:
    • Those pods belong to distinct applications that should have isolated privileges.
    • There are no app-specific ServiceAccounts/roles/namespaces.

This suggests both namespace and identity segregation are not being used.

5. Review cluster-wide workloads that omit a namespace (using default implicitly)

To spot resources that may be created without specifying -n or metadata.namespace:

kubectl get deploy,sts,ds,job,cronjob,svc,ingress,cm,secret --all-namespaces | grep ' default '

What to look for (potential problems):

  • Any production or shared system component appearing in default.
  • Patterns showing that most application resources land in default instead of in dedicated namespaces.

Use these observations to decide:

  • Which applications or components currently in default should be moved into dedicated namespaces.
  • What namespace structure (per app, per team, per environment) best supports your access control and segregation requirements.
Automation
#!/usr/bin/env bash
#
# Report all workload and access-control resources that are using the "default" namespace.
# Run on: any machine with kubectl access and current-context set to the target cluster.
# Requirements: kubectl, jq

set -euo pipefail

# Helper: safe kubectl get with nice headers
kget() {
local ns="$1"; shift
local kind="$1"; shift
echo
echo "=== ${kind} in namespace '${ns}' ==="
kubectl get "${kind}" -n "${ns}" -o wide --ignore-not-found
}

echo "Cluster context: $(kubectl config current-context)"
echo "Reporting use of the 'default' namespace..."
echo

# 1. Basic inventory of the 'default' namespace
echo "=== Namespaces summary (showing if 'default' exists) ==="
kubectl get ns default || true
echo

echo "=== Resource counts by namespace (workloads, services, secrets, configmaps) ==="
kubectl get deploy,ds,sts,cronjob,job,po,svc,cm,secret --all-namespaces \
-o json \
| jq -r '
.items[]
| .metadata.namespace as $ns
| $ns // "default"
' 2>/dev/null \
| sort \
| uniq -c \
| sort -nr
echo

# 2. Detailed listing of all common resource types in 'default'
kget default deploy
kget default daemonset
kget default statefulset
kget default cronjob
kget default job
kget default pod
kget default svc
kget default ingress
kget default configmap
kget default secret
kget default pvc
kget default role
kget default rolebinding
kget default serviceaccount
kget default networkpolicy
kget default hpa
kget default pdb

# 3. ClusterRoles / ClusterRoleBindings that reference the default namespace explicitly
echo
echo "=== ClusterRoleBindings referencing ServiceAccounts in 'default' namespace ==="
kubectl get clusterrolebinding -o json \
| jq -r '
.items[]
| {
name: .metadata.name,
subjects: (.subjects // [])
}
| select([.subjects[]? | select(.kind=="ServiceAccount" and .namespace=="default")] | length > 0)
| .name
' 2>/dev/null \
| sed 's/^/clusterrolebinding\//'
echo

# 4. (Optional) Detect namespaces with no resources at all (for comparison)
echo "=== Namespaces with zero Deployments, StatefulSets, DaemonSets, or Services (for context) ==="
all_ns=$(kubectl get ns -o jsonpath='{.items[*].metadata.name}')
for ns in $all_ns; do
cnt=$(kubectl get deploy,ds,sts,svc -n "$ns" --ignore-not-found -o json \
| jq '.items | length')
if [ "$cnt" -eq 0 ]; then
echo "$ns"
fi
done

echo
echo "Report complete."

cat <<'EOF'

HOW TO INTERPRET THIS OUTPUT
----------------------------
This benchmark expects the "default" namespace not to be used for application or
tenant workloads. It is typically acceptable only for:
- Minimal bootstrap/system objects (if absolutely required by your platform/tooling).
- Temporary/testing resources in non-production clusters (by explicit policy).

Indicators of a problem:
- Any application Deployments/DaemonSets/StatefulSets/Jobs/CronJobs listed under:
=== * in namespace 'default' ===
- Any user-facing Services or Ingresses in the 'default' namespace.
- ConfigMaps/Secrets in 'default' that belong to real applications (e.g. database creds).
- ServiceAccounts, Roles, or RoleBindings in 'default' that are used by production apps.
- ClusterRoleBindings that grant powerful roles to ServiceAccounts in the 'default' namespace.

Use this report to:
1. Identify which teams/owners have workloads in 'default'.
2. Decide whether each resource must be migrated into a purpose-specific namespace.
3. Define a policy (e.g., admission control) to prevent future creation of resources
in the 'default' namespace, once migration is complete.

Note: This script does NOT change the cluster; it only reports current usage so
you can make manual, policy-driven decisions consistent with the benchmark.
EOF