Pod Security Standards

What are Pod Security Standards (PSS)?

Pod Security Standards (PSS) is a framework that enables engineers to share and restrict privileges for different kinds of pods and users. These allow or disallow access to users and resources in the clusters, thus securing the Kubernetes clusters and the complete environment efficiently. 

There are three types of policies that range between highly permissive and highly restrictive. Engineers can implement a policy type based on pod security requirements. These include:

  • Privileged: The policy purposely offers unrestricted access and targets trusted users who manage system-level and infrastructure-level workloads. The mechanism is synonymous with allow-by-default and is the opposite of deny-by-default. With this, all restrictions can be disabled.
  • Baseline: With baseline policies, operators and developers can easily manage common containerized workloads without access to privileged sections of the Kubernetes environment. These are for users who work on non-critical applications.
  • Restricted: The restricted policies harden Kubernetes by limiting access and privileges. This comes at the cost of compatibility and ease of communication between resources but makes the environment highly secure. It is for users, operators, and developers working on security-critical applications and low-trust users. 

Overall, Pod Security Standards outline security controls for Kubernetes resources and ensure cluster operations, workload behaviors, and environmental integrity are well maintained.

What is Pod Security Policy (PSP) and why was it deprecated?

Before the establishment of PSS, security used to be controlled using Pod Security Policy (PSP). One of its key limitations was that a pod must run a set of pre-defined conditions mentioned in the PSP to be recognized by the Kubernetes environment as a valid resource. Without the specifications, the pod would not be accepted into the system. 

Since Kubernetes v1.21, PSP was deprecated due to its limitations and complex nature. According to feedback from Kubernetes developers, PSPs were confusing, and engineers found it difficult to determine which PSPs to apply in a given scenario. As a result, unintentional configuration and specification errors would often occur, compromising the Kubernetes environment’s security. The admission controller has now been replaced by Pod Security Admission (PSA), which enforces the policies outlined by the Pod Security Standards.

Functionalities of Pod Security Standard

The Privileged policy functions like the mechanism of allow-by-default for various resources. However, Baseline and Restricted policies can control the following components with the corresponding policies:

Baseline

ControlPolicy
HostProcessDetermines how a pod is run in the host namespace. Privileged access to the host is disallowed in the baseline policy.

FEATURE STATE: Kubernetes v1.26 [stable]Restricted Fields:
spec.securityContext.runAsUser
spec.securityContext.runAsGroup
spec.securityContext.runAsNonRoot
spec.securityContext.privilegedAllowed

Values
Undefined/nil
false
Host NamespacesSharing the host namespaces must be disallowed.
Restricted Fields:
spec.hostNetwork
spec.hostPID
spec.hostIPC

Allowed Values:
Undefined/null
false
Privileged ContainersPrivileged Pods disable most security mechanisms and must be disallowed.
Restricted Fields
spec.containers[*].securityContext.privileged
spec.initContainers[*].securityContext.privileged
spec.ephemeralContainers[*].securityContext.privileged

Allowed Values:
Undefined/null
false
CapabilitiesAdding additional capabilities beyond those listed below must be disallowed.
Restricted Fields
spec.containers[*].securityContext.capabilities.add
spec.initContainers[*].securityContext.capabilities.add
spec.ephemeralContainers[*].securityContext.capabilities.add

Allowed Values
Undefined/nil
AUDIT_WRITE
CHOWN
DAC_OVERRIDE
FOWNER
FSETID
KILL
MKNOD
NET_BIND_SERVICE
SETFCAP
SETGID
SETPCAP
SETUID
SYS_CHROOT
HostPath VolumesHostPath volumes must be forbidden.
Restricted Fields
spec.volumes[*].hostPath

Allowed Values
Undefined/nil
Host PortsHostPorts should be disallowed entirely (recommended) or restricted to a known list

Restricted Fields
spec.containers[*].ports[*].hostPort
spec.initContainers[*].ports[*].hostPort
spec.ephemeralContainers[*].ports[*].hostPort

Allowed Values
Undefined/null
Known list (not supported by the built-in Pod Security Admission controller)
0
AppArmorOn supported hosts, the runtime/default AppArmor profile is applied by default. The baseline policy should prevent overriding or disabling the default AppArmor profile, or restrict overrides to an allowed set of profiles.

Restricted Fields
metadata.annotations[“container.apparmor.security.beta.kubernetes.io/*”]

Allowed Values
Undefined/nil
runtime/default
localhost/*
SELinuxSetting the SELinux type is restricted, and setting a custom SELinux user or role option is forbidden.

Restricted Fields
spec.securityContext.seLinuxOptions.type
spec.containers[*].securityContext.seLinuxOptions.type
spec.initContainers[*].securityContext.seLinuxOptions.type
spec.ephemeralContainers[*].securityContext.seLinuxOptions.type

Allowed Values
Undefined/””
container_t
container_init_t
container_kvm_t
————————————————-
Restricted Fields
spec.securityContext.seLinuxOptions.user
spec.containers[*].securityContext.seLinuxOptions.user
spec.initContainers[*].securityContext.seLinuxOptions.user
spec.ephemeralContainers[*].securityContext.seLinuxOptions.user
spec.securityContext.seLinuxOptions.role
spec.containers[*].securityContext.seLinuxOptions.role
spec.initContainers[*].securityContext.seLinuxOptions.role
spec.ephemeralContainers[*].securityContext.seLinuxOptions.role

Allowed Values
Undefined/””
/proc Mount TypeThe default /proc masks are set up to reduce attack surface, and should be required.

Restricted Fields
spec.containers[*].securityContext.procMount
spec.initContainers[*].securityContext.procMount
spec.ephemeralContainers[*].securityContext.procMountAllowed ValuesUndefined/nilDefault
SeccompSeccomp profile must not be explicitly set to Unconfined.

Restricted Fields
spec.securityContext.seccompProfile.type
spec.containers[*].securityContext.seccompProfile.type
spec.initContainers[*].securityContext.seccompProfile.type
spec.ephemeralContainers[*].securityContext.seccompProfile.type

Allowed Values
Undefined/nilRuntimeDefaultLocalhost
SysctlsSysctls can disable security mechanisms or affect all containers on a host, and should be disallowed except for an allowed “safe” subset. A sysctl is considered safe if it is namespaced in the container or the Pod, and it is isolated from other Pods or processes on the same Node.

Restricted Fields
spec.securityContext.sysctls[*].name

Allowed Values
Undefined/nil
kernel.shm_rmid_forced
net.ipv4.ip_local_port_range
net.ipv4.ip_unprivileged_port_start
net.ipv4.tcp_syncookies
net.ipv4.ping_group_range

Restricted

Restricted comprises everything that comes under Baseline Policy. Furthermore, it also includes the following:

ControlPolicy
Volume TypesThe restricted policy only permits the following volume types.

Restricted Fields
spec.volumes[*]

Allowed Values
Every item in the spec.volumes[*] list must set one of the following fields to a non-null value:
spec.volumes[*].configMap
spec.volumes[*].csi
spec.volumes[*].downwardAPI
spec.volumes[*].emptyDir
spec.volumes[*].ephemeral
spec.volumes[*].persistentVolumeClaim
spec.volumes[*].projected
spec.volumes[*].secret
Privilege Escalation (v1.8+)Privilege escalation (such as via set-user-ID or set-group-ID file mode) should not be allowed. This is Linux only policy in v1.25+ (spec.os.name != windows)

Restricted Fields
spec.containers[*].securityContext.allowPrivilegeEscalation
spec.initContainers[*].securityContext.allowPrivilegeEscalation
spec.ephemeralContainers[*].securityContext.allowPrivilegeEscalation

Allowed Values
false
Running as Non-rootContainers must be required to run as non-root users.

Restricted Fields
spec.securityContext.runAsNonRoot
spec.containers[*].securityContext.runAsNonRoot
spec.initContainers[*].securityContext.runAsNonRoot
spec.ephemeralContainers[*].securityContext.runAsNonRoot

Allowed Values
true

The container fields may be undefined/nil if the pod-level spec.securityContext.runAsNonRoot is set to true.
Running as Non-root user (v1.23+)Containers must not set runAsUser to 0

Restricted Fields
spec.securityContext.runAsUser
spec.containers[*].securityContext.runAsUser
spec.initContainers[*].securityContext.runAsUser
spec.ephemeralContainers[*].securityContext.runAsUser

Allowed Values
any non-zero value
undefined/null
Seccomp (v1.19+)Seccomp profile must be explicitly set to one of the allowed values. Both the Unconfined profile and the absence of a profile are prohibited. This is Linux only policy in v1.25+ (spec.os.name != windows)

Restricted Fields
spec.securityContext.seccompProfile.type
spec.containers[*].securityContext.seccompProfile.type
spec.initContainers[*].securityContext.seccompProfile.type
spec.ephemeralContainers[*].securityContext.seccompProfile.type

Allowed Values
RuntimeDefault
Localhost

The container fields may be undefined/nil if the pod-level spec.securityContext.seccompProfile.type field is set appropriately. Conversely, the pod-level field may be undefined/nil if _all_ container- level fields are set.
Capabilities (v1.22+)Containers must drop ALL capabilities, and are only permitted to add back the NET_BIND_SERVICE capability. This is Linux only policy in v1.25+ (.spec.os.name != “windows”)

Restricted Fields
spec.containers[*].securityContext.capabilities.drop
spec.initContainers[*].securityContext.capabilities.drop
spec.ephemeralContainers[*].securityContext.capabilities.drop

Allowed Values
Any list of capabilities that includes ALL
————————————————-
Restricted Fields

spec.containers[*].securityContext.capabilities.add
spec.initContainers[*].securityContext.capabilities.add
spec.ephemeralContainers[*].securityContext.capabilities.add

Allowed Values
Undefined/nil
NET_BIND_SERVICE

Benefits of Pod Security Standards

  • With Pod Security Standards, securing Kubernetes clusters becomes simpler, more straightforward, and more efficient. The framework enhances the security posture of the clusters.
  • The policies prevent unauthorized actions from low-trust users and other resources, thus preventing potential vulnerabilities that can be exploited.
  • With Restricted and Baseline policies, pod security is hardened by leveraging the least privilege principles. As a result, the attack surface is reduced, and the impact of a potential malicious attack is minimized.
  • Pod Security Standards also allow engineers to configure the Kubernetes resources and environments that align with industry security standards and regulatory frameworks, which help with cluster security.

Working with Pod Security Standards

Pod Security Admission is the admission controller to enforce Pod Security Standard policies. This occurs via the following three modes:

  • Enforce: With this, policy violations in a pod will result in its rejection.
  • Audit: Pods with policy violations will be allowed, but the event in the audit log will be annotated with “audit.”
  • Warn: Pods with policy violations will be allowed, but the users will receive a warning. 

Example of Namespace Configuration using PSS and PSA

In the below example, the namespace is configured with a cluster-wide setting, and the configuration occurs by default. The labels are commented, but by uncommenting, the PSS can the PSA can implement policies for the namespace.

apiVersion: v1
kind: Namespace
metadata:
  name: psa-pss-test-ns
  labels:    
    # pod-security.kubernetes.io/enforce: privileged
    # pod-security.kubernetes.io/audit: privileged
    # pod-security.kubernetes.io/warn: privileged
    
    # pod-security.kubernetes.io/enforce: baseline
    # pod-security.kubernetes.io/audit: baseline
    # pod-security.kubernetes.io/warn: baseline
    
    # pod-security.kubernetes.io/enforce: restricted
    # pod-security.kubernetes.io/audit: restricted
    # pod-security.kubernetes.io/warn: restricted

Limitations and considerations

  • Although Pod Security Standards are less complex than its predecessor PSP (Pod Security Policies), adopting and maintaining the specifications is challenging due to the dynamic nature of the environment and resource usage.
  • The hardening of pod security causes compatibility issues and impacts the seamless functionality of applications.
  • While using Pod Security Standards and Pod Security Admission, it is important to understand how the application performances will be impacted and to what extent the security can be prioritized over the performance. Overall, it must be about creating a balance between the two factors.
Stay up to date