๐Ÿ‘ค
๐Ÿ›ก๏ธ Module 4 โ€ข 4 Labs โ€ข Est. 45 min โ€ข Advanced

Security & RBAC

Secure your cluster with RBAC, ServiceAccounts, Secrets, NetworkPolicies, SecurityContexts, and Pod Security Standards.

1. The Kubernetes Security Model

Kubernetes security has multiple layers, often described as the "4 Cs": Cloud (infrastructure security), Cluster (RBAC, admission controllers), Container (image scanning, security contexts), and Code (application security). This module focuses on the Cluster and Container layers.

Principle of Least Privilege: Every identity (user, service, pod) should have only the minimum permissions needed to do its job, and nothing more.

2. Authentication vs Authorization

  • Authentication (AuthN โ€” Who are you?): Kubernetes doesn't manage users directly. It relies on client certificates, bearer tokens, or OIDC providers (like Google, Okta). ServiceAccounts are the internal identity mechanism for pods.
  • Authorization (AuthZ โ€” What can you do?): RBAC is the dominant authorization mechanism. It checks whether an authenticated subject can perform a specific action on a specific resource.
  • Admission Control: A final gate after AuthZ. Admission controllers can mutate or validate requests (e.g., inject sidecar containers, deny privileged pods).

3. RBAC โ€” Role-Based Access Control

RBAC uses four core objects to control access:

graph TD; subgraph Subjects - Who U[User / Group] SA[ServiceAccount] end subgraph Bindings - Glue RB[RoleBinding\nNamespace-scoped] CRB[ClusterRoleBinding\nCluster-wide] end subgraph Permissions - What R[Role\nNamespace-scoped rules] CR[ClusterRole\nCluster-wide rules] end U --> RB SA --> RB U --> CRB SA --> CRB RB --> R RB --> CR CRB --> CR style RB fill:#8b5cf6,stroke:#a78bfa,stroke-width:2px,color:#fff style CRB fill:#8b5cf6,stroke:#a78bfa,stroke-width:2px,color:#fff
rbac-full-example.yaml
## Step 1: Create a ServiceAccount (identity for a Pod)
apiVersion: v1
kind: ServiceAccount
metadata:
  name: monitoring-sa
  namespace: monitoring
---
## Step 2: Create a Role (define permissions, namespace-scoped)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: monitoring
  name: pod-reader
rules:
- apiGroups: [""]               # "" = core API group (pods, services, configmaps)
  resources: ["pods", "pods/log"]
  verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list"]
---
## Step 3: Bind the Role to the ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods-binding
  namespace: monitoring
subjects:
- kind: ServiceAccount
  name: monitoring-sa
  namespace: monitoring
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

RBAC Verification Commands

bash
# Check what your current user can do
kubectl auth can-i create deployments

# Check what a ServiceAccount can do
kubectl auth can-i list pods \
  --as=system:serviceaccount:monitoring:monitoring-sa \
  -n monitoring

# See all permissions for a subject
kubectl auth can-i --list --as=system:serviceaccount:monitoring:monitoring-sa

4. Secrets โ€” Managing Sensitive Data

Secrets store sensitive information: passwords, API keys, TLS certificates. They are base64-encoded (reversible) โ€” this is for transport safety, not encryption.

secrets.yaml
# Create secret imperatively (recommended โ€” avoids storing plaintext in YAML)
kubectl create secret generic db-creds \
  --from-literal=username=admin \
  --from-literal=password=S3cur3P@ss!

# Reference in a Pod (as env vars โ€” most common approach)
spec:
  containers:
  - name: app
    env:
    - name: DB_USER
      valueFrom:
        secretKeyRef:
          name: db-creds
          key: username
    - name: DB_PASS
      valueFrom:
        secretKeyRef:
          name: db-creds
          key: password

# Or mount as files (some apps read from /etc/secrets)
    volumeMounts:
    - name: secret-vol
      mountPath: /etc/secrets
      readOnly: true
  volumes:
  - name: secret-vol
    secret:
      secretName: db-creds
โš ๏ธ Secrets are NOT encrypted at rest by default. Anyone with etcd access can read them. In production: enable Encryption at Rest, or use an external secrets manager like HashiCorp Vault, AWS Secrets Manager, or Sealed Secrets.

5. SecurityContexts โ€” Container-Level Security

A securityContext defines privilege and access control for a Pod or individual container. This is your primary line of defense against container escapes.

secure-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: secure-app
spec:
  securityContext:               # Pod-level (applies to all containers)
    runAsNonRoot: true           # Reject containers that try to run as root
    runAsUser: 1000              # Run as UID 1000
    fsGroup: 2000                # Volume files owned by GID 2000
  containers:
  - name: app
    image: my-app:v1
    securityContext:             # Container-level (overrides Pod-level)
      readOnlyRootFilesystem: true     # Cannot modify container filesystem
      allowPrivilegeEscalation: false  # Cannot gain more privileges than parent
      capabilities:
        drop:
        - ALL                    # Drop ALL Linux capabilities (best practice)
        add:
        - NET_BIND_SERVICE       # Add back only what's needed (bind port <1024)

Security Hardening Checklist

Container Security

  • โœ… runAsNonRoot: true
  • โœ… readOnlyRootFilesystem: true
  • โœ… allowPrivilegeEscalation: false
  • โœ… capabilities.drop: [ALL]
  • โœ… Use non-root base images (distroless, alpine)
  • โœ… Scan images for CVEs (Trivy, Snyk)

Cluster Security

  • โœ… Enable RBAC (on by default since K8s 1.6)
  • โœ… Rotate ServiceAccount tokens
  • โœ… Enable audit logging
  • โœ… Encrypt Secrets at rest
  • โœ… Apply NetworkPolicies
  • โœ… Use Pod Security Standards (Baseline/Restricted)

6. Pod Security Standards (PSS)

Since Kubernetes 1.25, Pod Security Standards replaced the deprecated PodSecurityPolicy. PSS are enforced at the namespace level via labels:

  • Privileged: No restrictions. Only for trusted system workloads.
  • Baseline: Prevents known privilege escalations. Good for most workloads.
  • Restricted: Heavily restricted, follows Pod hardening best practices. Required for high-security workloads.
bash โ€” Apply PSS to a namespace
kubectl label namespace production \
  pod-security.kubernetes.io/enforce=restricted \
  pod-security.kubernetes.io/warn=restricted \
  pod-security.kubernetes.io/audit=restricted
โ–ถ Terminal Simulator
โ–ฒ
K8s.Learn Simulator connected.
Type 'help' for available commands.
root@k8s-master:~#