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:
fsGroup | Sets 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 |
supplementalGroups | Adds group IDs |
sysctls | Kernel 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:
allowPrivilegeEscalation | Blocks privilege elevation |
capabilities | Add/drop Linux capabilities |
privileged | Full access to host (avoid this!) |
procMount | Controls /proc mount behavior |
readOnlyRootFilesystem | Enforce 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.
| Field | Set at Pod Level | Set at Container Level | Who Wins (every time)? |
|---|---|---|---|
| runAsNonRoot | ✅ | ✅ | Container |
runAsGroup | ✅ | ✅ | Container |
runAsUser | ✅ | ✅ | Container |
seccompProfile | ✅ | ✅ | Container |
seLinuxOptions | ✅ | ✅ | Container |
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
fsGroupin container-levelsecurityContext(it won’t work) - Ignoring
seccompProfile(should beRuntimeDefaultat minimum) - Assuming container settings apply to all containers
Conclusion
- Use
PodSecurityContextto define shared, secure general defaults across containers in a pod. - Use
ContainerSecurityContextto harden specific individual containers.
By following best practices and understanding the scopes, you’ll build safer Kubernetes deployments.
External Links
- Kubernetes Security Context – https://kubernetes.io/docs/tasks/configure-pod-container/security-context
- Pod securityContext – https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.33/#podsecuritycontext-v1-core
- Container securityContext – https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.33/#securitycontext-v1-core