The Default Namespace Should Not Be Used
More Info:
Kubernetes provides a default namespace, where objects are placed if no namespace is specified for them. Placing objects in this namespace makes application of RBAC and other controls more difficult.
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)
- NIS2 Directive
- 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
-
List all objects currently in the
defaultnamespace- Run on: any machine with
kubectlaccess - Command:
kubectl api-resources --verbs=list --namespaced -o name \| xargs -n 1 kubectl get -n default --ignore-not-found
- Review which workloads, services, config, and secrets are currently living in
default.
- Run on: any machine with
-
Identify which
default-namespace objects are non-system and should be moved- Run on: any machine with
kubectlaccess - Commands (examples for common types):
kubectl get deploy,sts,ds,job,cronjob -n default -o widekubectl get svc,ingress -n default -o widekubectl get configmap,secret -n default
- Decide, in coordination with application owners, which of these are user/application workloads (not temporary tests or intentionally shared infra) and should be isolated into their own namespace(s).
- Run on: any machine with
-
Create or confirm appropriate target namespaces for each application or team
- Run on: any machine with
kubectlaccess - For each logical application/team you identified:
kubectl create namespace <app-or-team-namespace-name>
- If a namespace already exists for that application/team, skip creation and just record it as the target.
- Run on: any machine with
-
Plan and apply namespace-specific RBAC and policies before moving workloads
- Run on: any machine with
kubectlaccess - Gather current RBAC and policy references that may rely on
default:kubectl get role,rolebinding -Akubectl get clusterrole,clusterrolebindingkubectl get networkpolicy -Akubectl get resourcequota,limitrange -A - For each target namespace, define or update:
Role/RoleBinding(orClusterRoleBindingsubjects) for the right users/service accountsResourceQuota/LimitRangeas neededNetworkPolicyto enforce appropriate isolation
- Apply these manifests to the target namespaces before moving the workloads.
- Run on: any machine with
-
Migrate objects from
defaultinto their target namespaces- Run on: any machine with
kubectlaccess - For each object selected for migration:
- Export manifest from
default:kubectl get <kind> <name> -n default -o yaml > /tmp/<name>.yaml - Edit
/tmp/<name>.yaml:- Remove
metadata.resourceVersion,metadata.uid,metadata.creationTimestamp,status, and anyownerReferencesthat would block recreation. - Change
metadata.namespace: defaulttometadata.namespace: <target-namespace>.
- Remove
- Apply to the target namespace:
kubectl apply -f /tmp/<name>.yaml
- After confirming the new object is running and healthy, delete the old one from
default:kubectl delete <kind> <name> -n default
- Export manifest from
- For services and ingresses, coordinate any DNS or client impact and validate traffic after migration.
- Run on: any machine with
-
Verify that
defaultis no longer used for application resources- Run on: any machine with
kubectlaccess - Re-run a comprehensive check:
kubectl api-resources --verbs=list --namespaced -o name \| xargs -n 1 kubectl get -n default --ignore-not-found
- Confirm that only objects you explicitly accept in
default(if any) remain, and that new deployment processes specify non-defaultnamespaces (e.g., by checking CI/CD manifests and Helm values).
- Run on: any machine with
Using kubectl
Using kubectl
Run these commands from any machine with kubectl access.
-
List all objects in the
defaultnamespacekubectl get all -n defaultProblem indication: Any non‑system workloads (your applications, databases, jobs, etc.) appearing here suggest the default namespace is being used inappropriately.
-
Enumerate all resource types in the
defaultnamespace# Workloads and serviceskubectl get deploy,sts,ds,po,svc,ing,job,cronjob -n default# Config and access-related objectskubectl get cm,secret,sa,role,rolebinding,pdb,hpa -n defaultProblem indication: Application deployments, services, ingresses, configmaps, secrets, roles/rolebindings, etc. in
default(other than intentional exceptions you explicitly accept) indicate a policy issue. -
Identify which users/teams are using
defaultkubectl get deploy -n default -o widekubectl get po -n default -o yaml | grep -E 'ownerReferences:|name:|kind:' -nProblem indication: Objects clearly associated with specific applications or teams (by name or labels/annotations) show that these workloads should likely be moved into dedicated namespaces.
-
Check for RBAC targeting the
defaultnamespacekubectl get role,rolebinding -n default -o wideProblem indication: Custom
Role/RoleBindingobjects indefault(especially granting broad access) indicate that security controls are being applied directly todefaultinstead of to dedicated namespaces. -
Confirm whether
defaultis referenced in manifests (optional, if you have them locally)
From your manifest repository or local directory:grep -Rni --include='*.yml' --include='*.yaml' 'namespace:\s*default' .Problem indication: Manifests explicitly setting
namespace: defaultsuggest an ongoing practice of deploying into the default namespace.
These commands only surface current usage. A human must decide which objects (if any) are acceptable in default and plan migration of others into purpose‑specific namespaces.
Automation
#!/usr/bin/env bash
#
# Report all resources currently using the "default" namespace
# Requires: kubectl, access to all relevant API groups
set -euo pipefail
# 1) Basic sanity check
kubectl get ns default >/dev/null 2>&1 || {
echo "default namespace not found; nothing to report."
exit 0
}
echo "=== Resources in the 'default' namespace (names only) ==="
kubectl get all -n default
echo
echo "=== ClusterRoles / Roles / RoleBindings / ClusterRoleBindings referencing 'default' ==="
echo "# Roles/RoleBindings scoped to the default namespace:"
kubectl get role,rolebinding -n default -o wide || true
echo
echo "# ClusterRoleBindings that reference ServiceAccounts in the default namespace:"
kubectl get clusterrolebinding -o json \
| jq -r '
.items[]
| select(.subjects != null)
| select(
any(.subjects[]?; .kind=="ServiceAccount" and .namespace=="default")
)
| [.metadata.name,
([.subjects[]? | select(.kind=="ServiceAccount" and .namespace=="default") | .name] | join(","))]
| @tsv
' 2>/dev/null \
| awk 'BEGIN{print "CLUSTERROLEBINDING\tSERVICEACCOUNTS_IN_DEFAULT_NS"}
{print}' || echo "jq not available or no matches."
echo
echo "=== NetworkPolicies in the 'default' namespace ==="
kubectl get networkpolicy -n default || true
echo
echo "=== Ingresses in the 'default' namespace ==="
kubectl get ingress -n default || true
echo
echo "=== ConfigMaps and Secrets in the 'default' namespace ==="
kubectl get configmap,secret -n default || true
echo
echo "=== Events in the 'default' namespace (for recent activity context) ==="
kubectl get events -n default --sort-by=.lastTimestamp | tail -n 50 || true
echo
echo "=== Summary: count of objects by kind in the 'default' namespace ==="
kubectl api-resources --namespaced=true --verbs=list -o name \
| while read -r r; do
count=$(kubectl get "$r" -n default --no-headers 2>/dev/null | wc -l | tr -d ' ')
if [ "$count" -gt 0 ]; then
printf "%-40s %s\n" "$r" "$count"
fi
done
echo
echo "=== Guidance: How to interpret this output ==="
cat <<'EOF'
Any non-system workload or configuration appearing above in the "default" namespace
should be reviewed. In particular, these indicate a problem with this control:
- Pods, Deployments, StatefulSets, DaemonSets, Jobs, CronJobs, or Services in the
default namespace that belong to application teams.
- ServiceAccounts in the default namespace that are bound via (Cluster)RoleBindings
and used by applications.
- ConfigMaps, Secrets, Ingresses, NetworkPolicies in the default namespace that
are part of application deployments.
Desired state: only temporary/test items (if allowed by policy) or explicitly
approved workloads should exist in the default namespace; all regular workloads
should be moved to dedicated, named namespaces.
EOF