Scope

LevelPathPrecedence
Podspec.securityContextApplies to all containers
Containerspec.containers[].securityContextOverrides pod-level

Not a separate resource: fields on Pod/Deployment template.

Pod level vs container level

spec:
  securityContext:                  # POD level
    runAsUser: 1000
    runAsGroup: 3000
    runAsNonRoot: true
    fsGroup: 2000                   # GID for volume ownership
  containers:
  - name: app
    image: myapp:1.0
    securityContext:                # CONTAINER level: overrides pod level
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop:
        - ALL
        add:
        - NET_BIND_SERVICE

Key fields

FieldLevelEffect
runAsUserPod/ContainerUID for process
runAsNonRootPod/ContainerRefuse to run as UID 0
readOnlyRootFilesystemContainerBlock writes to /
allowPrivilegeEscalationContainerBlock sudo/setuid
capabilities.drop: [ALL]ContainerRemove all Linux capabilities
capabilities.add: [NET_BIND_SERVICE]ContainerAllow binding to port <1024
fsGroupPodVolumes owned by this GID
privileged: trueContainerFull host access: avoid

seccompProfile

securityContext:
  seccompProfile:
    type: RuntimeDefault    # RuntimeDefault | Localhost | Unconfined
  • RuntimeDefault: required for restricted PSS
  • Unconfined: blocked by restricted PSS

Pod Security Standards (PSS)

Namespace-level policy via Pod Security admission (replaced PodSecurityPolicy in 1.25).

StandardKey requirements
privilegedNo restrictions
baselineNo privileged containers, no host namespaces, no dangerous capabilities
restrictedbaseline + runAsNonRoot, drop ALL caps, seccompProfile: RuntimeDefault

Restricted-compliant container

spec:
  securityContext:
    runAsNonRoot: true
    seccompProfile:
      type: RuntimeDefault
  containers:
  - name: app
    image: bitnami/nginx:latest    # non-root image
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop: [ALL]
    volumeMounts:
    - name: tmp
      mountPath: /tmp
    - name: cache
      mountPath: /var/cache/nginx
  volumes:
  - name: tmp
    emptyDir: {}
  - name: cache
    emptyDir: {}
kubectl get ns production --show-labels | grep pod-security

Exam gotchas

  • Hardening pattern: runAsNonRoot: true + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities.drop: [ALL]
  • runAsNonRoot: true + nginx image → CreateContainerConfigError (runs as root); use bitnami/nginx or set runAsUser
  • Container-level wins over pod-level for same attribute
  • violates PodSecurity "restricted" → add seccompProfile: RuntimeDefault and drop capabilities
  • privileged: true fails on baseline and restricted namespaces