Skip to content

Security Context

Overview

Security context defines privilege and access control settings for pods and containers.


Pod-Level vs Container-Level

LevelScopeFields
PodAll containersrunAsUser, runAsGroup, fsGroup, seccompProfile
ContainerSingle containerAll pod-level + capabilities, privileged, readOnlyRootFilesystem

Container-level overrides pod-level.


Common Fields

yaml
securityContext:
  runAsUser: 1000          # UID to run as
  runAsGroup: 3000         # GID for processes
  runAsNonRoot: true       # Must not run as root
  fsGroup: 2000            # GID for volume ownership
  readOnlyRootFilesystem: true
  allowPrivilegeEscalation: false
  privileged: false
  capabilities:
    add: ["NET_ADMIN"]
    drop: ["ALL"]

Pod-Level Security Context

yaml
apiVersion: v1
kind: Pod
metadata:
  name: security-demo
spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 3000
    fsGroup: 2000
  containers:
  - name: app
    image: busybox
    command: ["sh", "-c", "id && sleep 3600"]

Container-Level Security Context

yaml
apiVersion: v1
kind: Pod
metadata:
  name: container-security
spec:
  containers:
  - name: app
    image: busybox
    command: ["sh", "-c", "sleep 3600"]
    securityContext:
      runAsUser: 2000
      runAsNonRoot: true
      readOnlyRootFilesystem: true
      allowPrivilegeEscalation: false
      capabilities:
        drop: ["ALL"]

Run as Non-Root

yaml
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
  containers:
  - name: app
    image: nginx
    # Will fail if image tries to run as root

Capabilities

Linux capabilities for fine-grained privileges:

yaml
securityContext:
  capabilities:
    add: ["NET_ADMIN", "SYS_TIME"]
    drop: ["ALL"]

Common capabilities:

  • NET_ADMIN - Network configuration
  • SYS_TIME - Modify system clock
  • CHOWN - Change file ownership
  • DAC_OVERRIDE - Bypass file permissions

Read-Only Root Filesystem

yaml
containers:
- name: app
  image: nginx
  securityContext:
    readOnlyRootFilesystem: true
  volumeMounts:
  - name: tmp
    mountPath: /tmp      # Writable temp directory
  - name: cache
    mountPath: /var/cache/nginx
volumes:
- name: tmp
  emptyDir: {}
- name: cache
  emptyDir: {}

fsGroup for Volume Access

yaml
spec:
  securityContext:
    fsGroup: 2000        # Files in mounted volumes owned by GID 2000
  containers:
  - name: app
    image: busybox
    volumeMounts:
    - name: data
      mountPath: /data   # All files here owned by group 2000
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: my-pvc

Verify Security Context

bash
# Check user/group inside pod
kubectl exec <pod-name> -- id
# Output: uid=1000 gid=3000 groups=2000

# Check file ownership
kubectl exec <pod-name> -- ls -la /data

Released under the MIT License.