Kubernetes deprecated Pod Security Policy (PSP) in version 1.21 and removed it entirely in 1.25. It was replaced by Pod Security Admission (PSA), which is enabled by default starting with v1.23. Talos Linux automatically enables and configures PSA to enforce Pod Security Standards. These Pod Security Standards define three policies that cover the security spectrum:Documentation Index
Fetch the complete documentation index at: https://docs.siderolabs.com/llms.txt
Use this file to discover all available pages before exploring further.
- Privileged: Unrestricted policy, providing the widest possible level of permissions.
- Baseline: Minimally restrictive policy.
- Restricted: Heavily restricted policy.
baseline profile to all namespaces, except for the kube-system namespace, which uses the privileged profile.
Default PSA configuration
Here is the default PSA configuration on Talos:- Enforces the
baselinesecurity profile by default. - Throws a warning, if the
restrictedprofile is violated, but does not enforce this profile.
Modify the default PSA configuration
You can modify this PSA policy by updating the generated machine configuration before the cluster is created or on the fly by using thetalosctl CLI utility.
Verify current admission plugin configuration with:
Workloads that satisfy the different security profiles
To deploy a workload that satisfies both thebaseline and restricted profiles, you must ensure that your workloads:
- Run as non-root users (UID 1000 or higher)
- Use read-only root filesystems where possible
- Minimize or eliminate kernel capabilities
restricted, baseline, or both profiles:
- A Deployment that satisfies the
restrictedprofile - A Deployment that meets
baselinerequirements butviolatesrestricted - A DaemonSet that violates both
restrictedandbaselineprofiles
Deployment that satisfies the restricted profile
This Deployment complies with therestricted profile and does not produce any errors or warnings when applied:
example-workload Deployment, it successfully creates the Deployment and deploys its pods:
- Command
- Output
- runAsNonRoot: true: Prevents the container from running as root.
- runAsUser and runAsGroup: Ensures a dedicated non-root user (UID/GID 1000) runs the process.
- fsGroup: Sets file system group ownership for shared volumes.
- seccompProfile: RuntimeDefault: Uses the default seccomp profile to restrict available system calls.
- allowPrivilegeEscalation: false: Blocks processes from gaining additional privileges.
- capabilities: drop: [ALL]: Removes unnecessary Linux capabilities.
Deployment that violates the restricted but meets baseline profile
Run the following command to create a Deployment that complies with thebaseline profile but violates the restricted profile:
Warning: would violate PodSecurity “restricted:latest”: allowPrivilegeEscalation != false (container “nginx” must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container “nginx” must set securityContext.capabilities.drop=[“ALL”]), runAsNonRoot != true (pod or container “nginx” must set securityContext.runAsNonRoot=true), seccompProfile (pod or container “nginx” must set securityContext.seccompProfile.type to “RuntimeDefault” or “Localhost”)
deployment.apps/nginx created
Despite these warnings, the deployment and its pods are still created successfully because it complies with the default Talos baseline security profile:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-85b98978db-j68l8 1/1 Running 0 2m3s
DaemonSet that fails both the restricted and baseline profiles
This DaemonSet violates both thebaseline and restricted profiles:
- An error is thrown, showing that the DaemonSet requests too much privileges:
Warning: would violate PodSecurity “restricted:latest”: host namespaces (hostNetwork=true, hostPID=true, hostIPC=true), privileged (container “debug-container” must not set securityContext.privileged=true), allowPrivilegeEscalation != false (container “debug-container” must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container “debug-container” must set securityContext.capabilities.drop=[“ALL”]), runAsNonRoot != true (pod or container “debug-container” must set securityContext.runAsNonRoot=true), seccompProfile (pod or container “debug-container” must set securityContext.seccompProfile.type to “RuntimeDefault” or “Localhost”)
daemonset.apps/debug-container created
- The DaemonSet object gets created but no pods are scheduled:
- When you describe the DaemonSet, the
Eventssection shows that Pod Security Admission errors are blocking pod creation:
$ kubectl describe ds debug-container
…
Warning FailedCreate 92s daemonset-controller Error creating: pods “debug-container-kwzdj” is forbidden: violates PodSecurity “baseline:latest”: host namespaces (hostNetwork=true, hostPID=true, hostIPC=true), privileged (container “debug-container” must not set securityContext.privileged=true)
This happens because the DaemonSet does not comply with the enforced baseline Pod Security profile.
Override the Pod Security Admission Configuration
You can override the Pod Security Admission configuration at the namespace level. This is especially useful for applications like Prometheus node exporter or storage solutions that require more relaxed Pod Security Standards. Using the DaemonSet workload example, you can update the enforced policy toprivileged for its namespace, which is the default namespace.
Troubleshooting common PSA error messages
Here are some typical error messages you’ll run into when a pod violates a PSA policy, along with what went wrong and how to fix it.- Pod denied because of restricted fields:
baseline profile. For example, the pod either allows privilege escalation or doesn’t force non-root user.
Fix: In the pod’s spec, make sure the container is set to run as a non-root user and cannot escalate its privileges. For example:
- Warnings for policy non-compliance:
- Pod denied due to host-level access:
emptyDir, a CSI volume, etc.) in your pod spec.
- Invalid namespace label value: