Lesson  in  DevSecOps in Practice: Container & Kubernetes Security

Namespace & RBAC Isolation

Apply different Pod Security Standard levels to dev, staging, and production namespaces. Create a service account scoped to the dev namespace and prove that a compromised dev account cannot list pods in production.

PSA Levels per Environment

Different Security Levels for Different Environments

Production workloads need strict controls. Development needs flexibility so engineers aren't blocked by warnings every minute. Apply different PSA levels per namespace to match each environment's risk profile.

Create the environment namespaces

kubectl create namespace dev
kubectl create namespace staging
kubectl create namespace production

Apply different PSA levels

# dev: warn only — pods run but developers see warnings
kubectl label namespace dev \
  pod-security.kubernetes.io/warn=baseline \
  pod-security.kubernetes.io/warn-version=latest

# staging: enforce baseline — blocks known privilege escalations
kubectl label namespace staging \
  pod-security.kubernetes.io/enforce=baseline \
  pod-security.kubernetes.io/enforce-version=latest

# production: enforce restricted — strictest standard
kubectl label namespace production \
  pod-security.kubernetes.io/enforce=restricted \
  pod-security.kubernetes.io/enforce-version=latest \
  pod-security.kubernetes.io/audit=restricted \
  pod-security.kubernetes.io/audit-version=latest

Test the same root-user pod across all three namespaces

cat > test-pod.yaml << 'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
  - name: app
    image: public.ecr.aws/docker/library/busybox:1.36
    command: ["sleep", "3600"]
    securityContext:
      runAsUser: 0
      privileged: false
EOF
kubectl apply -f test-pod.yaml -n dev && echo "dev: allowed (with warning)"
kubectl apply -f test-pod.yaml -n staging && echo "staging: allowed"
kubectl apply -f test-pod.yaml -n production 2>&1 | head -3

Expected:

dev: allowed (with warning)
staging: allowed
Error from server (Forbidden): violates PodSecurity "restricted:latest" ...

RBAC Namespace Scoping

A Compromised Dev Account Cannot Reach Production

Namespaces alone are not a security boundary. Combine them with RBAC and a compromised service account in dev cannot list pods in production.

Create a developer service account

kubectl create serviceaccount dev-user -n dev
cat > dev-role.yaml << 'EOF'
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: dev-access
  namespace: dev
rules:
- apiGroups: [""]
  resources: ["pods", "services", "configmaps"]
  verbs: ["get", "list", "watch", "create", "update", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: dev-access-binding
  namespace: dev
subjects:
- kind: ServiceAccount
  name: dev-user
  namespace: dev
roleRef:
  kind: Role
  apiGroup: rbac.authorization.k8s.io
  name: dev-access
EOF
kubectl apply -f dev-role.yaml

Verify namespace isolation

kubectl auth can-i list pods -n dev --as=system:serviceaccount:dev:dev-user
kubectl auth can-i list pods -n production --as=system:serviceaccount:dev:dev-user

Expected: yes / no

Cleanup

kubectl delete namespace dev staging production