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
fsGroup
in container-levelsecurityContext
(it won’t work) - Ignoring
seccompProfile
(should beRuntimeDefault
at minimum) - Assuming container settings apply to all containers
Conclusion
- Use
PodSecurityContext
to define shared, secure general defaults across containers in a pod. - Use
ContainerSecurityContext
to 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