DEV Community

Aisalkyn Aidarova
Aisalkyn Aidarova

Posted on

πŸ” Kubernetes Security Project

RBAC + ServiceAccounts + NetworkPolicy (End-to-End)

🎯 Goal

Understand who can do what and who can talk to whom inside Kubernetes.

You will:

  • Lock down API access using RBAC
  • Restrict pod-to-pod traffic using NetworkPolicy
  • See real failures (403, connection refused)
  • Learn how security incidents are prevented

Architecture

User
 β”œβ”€ kubectl (admin)
 β”‚
 β”œβ”€ Pod A (frontend)
 β”‚      ↓ allowed
 β”œβ”€ Pod B (backend)
 β”‚      ↓ blocked
 └─ Pod C (db)
Enter fullscreen mode Exit fullscreen mode

1️⃣ Create Namespace

kubectl create namespace secure-lab
Enter fullscreen mode Exit fullscreen mode

2️⃣ Create ServiceAccount (Non-Admin)

# sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: app-sa
  namespace: secure-lab
Enter fullscreen mode Exit fullscreen mode
kubectl apply -f sa.yaml
Enter fullscreen mode Exit fullscreen mode

3️⃣ Create Restricted Role (RBAC)

❌ No delete
❌ No secrets
βœ… Only read pods & services

# role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: secure-lab
  name: read-only-role
rules:
- apiGroups: [""]
  resources: ["pods", "services"]
  verbs: ["get", "list"]
Enter fullscreen mode Exit fullscreen mode

4️⃣ Bind Role to ServiceAccount

# rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-only-binding
  namespace: secure-lab
subjects:
- kind: ServiceAccount
  name: app-sa
  namespace: secure-lab
roleRef:
  kind: Role
  name: read-only-role
  apiGroup: rbac.authorization.k8s.io
Enter fullscreen mode Exit fullscreen mode
kubectl apply -f rolebinding.yaml
Enter fullscreen mode Exit fullscreen mode

5️⃣ Test RBAC FROM INSIDE A POD

kubectl run test-pod \
  -n secure-lab \
  --image=bitnami/kubectl \
  --serviceaccount=app-sa \
  --restart=Never \
  --rm -it -- sh
Enter fullscreen mode Exit fullscreen mode

Inside pod:

kubectl get pods      # βœ… allowed
kubectl delete pod x  # ❌ forbidden
kubectl get secrets   # ❌ forbidden
Enter fullscreen mode Exit fullscreen mode

Expected error

Error from server (Forbidden)
Enter fullscreen mode Exit fullscreen mode

6️⃣ Deploy 3-Tier App

Frontend

apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
  namespace: secure-lab
spec:
  replicas: 1
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
      - name: nginx
        image: nginx
Enter fullscreen mode Exit fullscreen mode

Backend

apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
  namespace: secure-lab
spec:
  replicas: 1
  selector:
    matchLabels:
      app: backend
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
      - name: app
        image: hashicorp/http-echo
        args: ["-text=backend"]
Enter fullscreen mode Exit fullscreen mode

Database

apiVersion: apps/v1
kind: Deployment
metadata:
  name: db
  namespace: secure-lab
spec:
  replicas: 1
  selector:
    matchLabels:
      app: db
  template:
    metadata:
      labels:
        app: db
    spec:
      containers:
      - name: app
        image: hashicorp/http-echo
        args: ["-text=db"]
Enter fullscreen mode Exit fullscreen mode

7️⃣ Test Networking (NO NetworkPolicy Yet)

kubectl run curl \
  -n secure-lab \
  --image=curlimages/curl \
  --rm -it -- sh
Enter fullscreen mode Exit fullscreen mode
curl backend
curl db
Enter fullscreen mode Exit fullscreen mode

βœ… Everything works (DEFAULT = allow all)


8️⃣ Apply NetworkPolicy (DENY ALL)

# deny-all.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all
  namespace: secure-lab
spec:
  podSelector: {}
  policyTypes:
  - Ingress
Enter fullscreen mode Exit fullscreen mode
kubectl apply -f deny-all.yaml
Enter fullscreen mode Exit fullscreen mode

9️⃣ Allow ONLY frontend β†’ backend

# allow-frontend.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: secure-lab
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
Enter fullscreen mode Exit fullscreen mode

πŸ”Ÿ Test Again

curl backend   # βœ… works
curl db        # ❌ blocked
Enter fullscreen mode Exit fullscreen mode

1️⃣1️⃣ What You Just Learned (INTERVIEW GOLD)

RBAC

  • Controls API access
  • Based on ServiceAccount
  • Prevents cluster takeover

NetworkPolicy

  • Controls pod-to-pod traffic
  • Default allow β†’ must deny explicitly
  • Requires CNI support

🚨 Real Production Incident You Now Understand

β€œA compromised pod could not access secrets or other services because RBAC and NetworkPolicy limited blast radius.”


FINAL INTERVIEW ANSWER (MEMORIZE)

β€œRBAC controls who can talk to the Kubernetes API.
NetworkPolicies control who can talk on the network.
Together they enforce least privilege and zero trust inside the cluster.”


Cleanup

kubectl delete namespace secure-lab
Enter fullscreen mode Exit fullscreen mode

Top comments (0)