๐Ÿ›ก๏ธ Kubernetes PSA Security Levels: What Exactly Do They Block? (In-depth Analysis)

Hello everyone! In our last post, we explored the concept and application of Pod Security Admission (PSA). Today, as a follow-up, we’ll delve deep into the core of PSA: the three security standards (Pod Security Standards), specifically examining “what configurations” they block and allow.

Are your Pods constantly falling into an Error state after applying PSA? Or are you struggling with what to fix when trying to apply the Restricted level? This article will provide a complete overview. ๐Ÿš€


1. Level 0: Privileged ๐Ÿ”“

“A lawless zone where everything is allowed”

This policy is intentionally completely open.

  • Restrictions: None
  • Allowed: Everything is possible, including host kernel access, root privileges, and host network usage.
  • Target Users: System-level Pods such as CNI plugins, storage drivers, and node management agents.

โš ๏ธ Caution

This level should never be applied to typical web applications or microservices. If hacked, the entire node will be at risk!


2. Level 1: Baseline ๐Ÿšง

“Minimum safety measures, standard for general applications”

This is a basic security policy. It prevents actions that could harm the host node through Privilege Escalation. Most common container images run well at this level without modification.

๐Ÿšซ Key Restrictions (What is blocked)

  1. Prohibition of Privileged Containers (privileged: true)
  • Prevents containers from directly accessing host devices.
  1. Prohibition of Host Namespace Sharing
  • hostNetwork: true: Containers cannot share the host’s network.
  • hostPID: true: Containers cannot view the host’s process IDs.
  • hostIPC: true: Containers cannot access inter-process communication on the host.
  1. Host Port Restrictions
  • Restricts occupying specific host ports (0-65535).
  1. Restrictions on Adding Specific Linux Capabilities
  • Prevents adding critical system capabilities (e.g., CAP_SYS_ADMIN, CAP_MKNOD).
  1. Prohibition of Dangerous Sysctls
  • Unsafe sysctls settings that modify kernel parameters cannot be used.
  1. HostPath Volumes
  • Note: Baseline does not completely prohibit HostPath itself, but it is recommended to strictly limit its use (actual blocking is performed at the Restricted level).

3. Level 2: Restricted ๐Ÿฐ

“Highest level of security, best practices”

This level includes all restrictions from Baseline and adds powerful rules to further isolate Pods and minimize the attack surface. You may need to modify your Pod spec (YAML) to pass this level.

๐Ÿšซ Additional Restrictions (Baseline + ฮฑ)

To pass this level, the following conditions must be explicitly set:

1. Prohibition of Root (UID 0) Execution ๐Ÿ‘ฎ

  • Containers must run as a non-Root user (not UID 0).
  • Required YAML setting:
securityContext:
  runAsNonRoot: true
  runAsUser: 1000 # Non-zero number

2. Prohibition of Privilege Escalation ๐Ÿ“‰

  • Prevents a process from gaining higher privileges than its parent process. This blocks actions like executing setuid binaries.
  • Required YAML setting:
containers:
  securityContext:
    allowPrivilegeEscalation: false

3. Linux Capabilities Initialization ๐Ÿ—‘๏ธ

  • Even capabilities provided by default by the container runtime must be dropped (DROP ALL). If necessary, only NET_BIND_SERVICE may be explicitly allowed.
  • Required YAML setting:
containers:
  securityContext:
    capabilities:
      drop: ["ALL"]

4. Volume Type Restrictions ๐Ÿ’พ

  • HostPath volumes, which can access the host’s file system, are absolutely forbidden.
  • Allowed volumes: Only Kubernetes abstract volumes such as ConfigMap, Secret, EmptyDir, PersistentVolumeClaim, DownwardAPI, and Projected are permitted.

5. Seccomp Profile Application ๐Ÿ›ก๏ธ

  • Seccomp, a system call filtering feature, must be configured.
  • Required YAML setting:
securityContext:
  seccompProfile:
    type: RuntimeDefault # or Localhost

๐Ÿง Summary Table at a Glance

Restriction Item Privileged Baseline Restricted
Privileged Containers Allowed โœ… Blocked ๐Ÿšซ Blocked ๐Ÿšซ
Host Network/PID/IPC Allowed โœ… Blocked ๐Ÿšซ Blocked ๐Ÿšซ
Linux Capabilities No restrictions Prohibit adding dangerous capabilities DROP ALL required
Root User Execution Allowed โœ… Allowed โœ… Forbidden (Non-Root required)
Privilege Escalation Allowed โœ… Allowed โœ… Forbidden (False required)
Volume Types All allowed (including HostPath) All allowed Core volumes only allowed (HostPath forbidden)

๐Ÿ’ก Best Practice YAML for Passing Restricted Level

Refer to the template below for deployment in a Restricted namespace. This is a security best practice.

apiVersion: v1
kind: Pod
metadata:
  name: secure-app
spec:
  # [Required] Pod-level security context
  securityContext:
    runAsNonRoot: true
    seccompProfile:
      type: RuntimeDefault
  containers:
  - name: app
    image: my-app:1.0
    # [Required] Container-level security context
    securityContext:
      allowPrivilegeEscalation: false
      runAsUser: 1001  # Root (0) forbidden
      capabilities:
        drop:
          - ALL # Drop all capabilities

Conclusion ๐Ÿ“

It’s advisable to start with Baseline to gain operational familiarity, then gradually strengthen to Restricted. Especially for web applications directly exposed to the internet, applying Restricted is strongly recommended.

Security is not an inconvenience, but a process that makes our services more robust! In the next post, I’ll bring some PSA troubleshooting examples. ๐Ÿ‘‹