Kubernetes securityContext Explained: Pod vs Container Scope and Best Practices

variety of locks on cable fence strand within city

When securing Kubernetes workloads, two YAML blocks cause a lot of confusion: PodSecurityContext and ContainerSecurityContext.

Both control how your containers run at the OS level—but they apply at different scopes and can overlap.

Note: There are some nuances in regards to Windows containers, please refer to the linked API documentation for those.

In this article, we’ll clearly explain:

  • Which common configs belongs to which spec
  • Where settings overlap
  • Some best practices for secure workloads

What Is PodSecurityContext?

PodSecurityContext applies security defaults to all containers in the pod. It’s defined under spec.securityContext.

Common PodSecurityContext settings:

fsGroupSets group ID for mounted volumes
runAsNonRoot*Indicates that the container must run as a non-root user
runAsUser*Default user ID for containers
runAsGroup*Default group ID
seccompProfile*System call filtering
seLinuxOptions*SELinux labels
supplementalGroupsAdds group IDs
sysctlsKernel settings for pod

*If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container.

# Example

spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 3000
    fsGroup: 2000
    seccompProfile:
      type: RuntimeDefault

What Is ContainerSecurityContext?

This is defined per container under containers[].securityContext. It affects only that container, and overrides Pod-level values. Its basically the securityContext sitting within your container definition right after your container name and image, etc.

Common ContainerSecurityContext settings:

allowPrivilegeEscalationBlocks privilege elevation
capabilitiesAdd/drop Linux capabilities
privilegedFull access to host (avoid this!)
procMountControls /proc mount behavior
readOnlyRootFilesystemEnforce read-only root
runAsNonRoot*Indicates that the container must run as a non-root user
runAsUser*Default user ID for containers
runAsGroup*Default group ID
seccompProfile*The seccomp options to use by this container.
seLinuxOptions*SELinux labels

*If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container.

# Example

containers:
- name: app
  image: myapp:latest
  securityContext:
    allowPrivilegeEscalation: false
    capabilities:
      drop: ["ALL"]
    readOnlyRootFilesystem: true

Overlapping Settings: Who Wins?

Container-level overrides take precedence if both are set.

FieldSet at Pod LevelSet at Container LevelWho Wins (every time)?
runAsNonRootContainer
runAsGroupContainer
runAsUserContainer
seccompProfileContainer
seLinuxOptionsContainer

Best Practices

1. Set defaults with PodSecurityContext first:
Use runAsUser, fsGroup, and seccompProfile at the pod level to apply secure defaults.

2. Then additionaly harden each container securityContext:
Use ContainerSecurityContext to drop capabilities, prevent privilege escalation, and enforce read-only filesystems.

3. Use fsGroup for volume permissions:
Especially useful for mounted volumes (e.g., PVCs) that require shared group access.

4. Drop all capabilities unless needed:

capabilities:
  drop: ["ALL"]

5. Never run as root unless necessary:
Running as UID 0 is rarely needed.


Full Example

# Example

apiVersion: v1
kind: Pod
metadata:
  name: my-secure-pod
spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 1000
    fsGroup: 2000
    seccompProfile:
      type: RuntimeDefault
  containers:
    - name: app
      image: nginx
      securityContext:
        allowPrivilegeEscalation: false
        capabilities:
          drop:
            - ALL
        readOnlyRootFilesystem: true

Common Mistakes

  • Putting fsGroup in container-level securityContext (it won’t work)
  • Ignoring seccompProfile (should be RuntimeDefault at minimum)
  • Assuming container settings apply to all containers

Conclusion

  1. Use PodSecurityContext to define shared, secure general defaults across containers in a pod.
  2. Use ContainerSecurityContext to harden specific individual containers.

By following best practices and understanding the scopes, you’ll build safer Kubernetes deployments.

External Links