Skip to main content
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:
  • Privileged: Unrestricted policy, providing the widest possible level of permissions.
  • Baseline: Minimally restrictive policy.
  • Restricted: Heavily restricted policy.
By default, Talos with the help of PSA, applies the 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:
This cluster-wide configuration:
  • Enforces the baseline security profile by default.
  • Throws a warning, if the restricted profile 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 the talosctl CLI utility. Verify current admission plugin configuration with:

Workloads that satisfy the different security profiles

To deploy a workload that satisfies both the baseline 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
To see how PSA treats workloads that violate security profiles, consider these examples that violate the restricted, baseline, or both profiles:
  • A Deployment that satisfies the restricted profile
  • A Deployment that meets baseline requirements but violates restricted
  • A DaemonSet that violates both restricted and baseline profiles

Deployment that satisfies the restricted profile

This Deployment complies with the restricted profile and does not produce any errors or warnings when applied:
When you apply this example-workload Deployment, it successfully creates the Deployment and deploys its pods:
This is because the Deployment follows Talos’ recommended security practices, which, as shown in the Deployment configuration, include:
  • 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 the baseline profile but violates the restricted profile:
Applying this Deployment triggers warnings indicating excessive privileges:
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 the baseline and restricted profiles:
When you apply this DaemonSet:
  • 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 Events section 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 to privileged for its namespace, which is the default namespace.
With this update, the DaemonSet is successfully running:

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.
  1. Pod denied because of restricted fields:
What’s happening: Your pod does not comply with the 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:
  1. Warnings for policy non-compliance:
What’s happening: PSA allows the pod to run, but it still flags issues that break the policy, like missing capability drops in this example. Fix: Explicitly drop capabilities, for example:
  1. Pod denied due to host-level access:
What’s happening: Your pod uses a host-level resource (e.g., a hostPath volume) or other disallowed field under the restricted profile. Fix: Remove or replace the hostPath (or other prohibited resource) and use a safer pattern (for example emptyDir, a CSI volume, etc.) in your pod spec.
  1. Invalid namespace label value:
What’s happening: The label value you used on the namespace is not one of the allowed options (privileged, baseline, restricted). Fix: Change the label to a valid value. For example: