Skip to main content

Implementing Pod Security Admission

1. Understanding Pod Security Standards

Standard Description Enforcement Level Key Controls
Privileged Allows pods to run with full root privileges and access to host resources. enforce Blocks privileged pods; requires securityContext.privileged: false
Baseline Minimum level of security for all pods; prevents most common vulnerabilities. enforce Requires allowPrivilegeEscalation: false, no host namespaces, and read-only root filesystems
Restricted Most secure standard; restricts pod capabilities and configurations. enforce Requires runAsNonRoot: true, no host namespaces, and strict resource limits

Example: Applying Pod Security Standard

apiVersion: v1
kind: Pod
metadata:
  name: example-pod
  labels:
    pod-security.kubernetes.io/enforce: restricted
spec:
  containers:
  - name: example-container
    image: nginx
    securityContext:
      runAsNonRoot: true
      allowPrivilegeEscalation: false
Note: Pod Security Admission is available in Kubernetes v1.23+ and requires the PodSecurity admission controller to be enabled.

2. Using Pod Security Admission

Policy Description Enforcement Level Example
enforce Denies pods that do not meet the policy requirements NEW
apiVersion: v1
kind: Pod
metadata:
  name: bad-pod
spec:
  containers:
  - name: test-container
    image: nginx
    securityContext:
      runAsNonRoot: false
audit Logs violations but allows pods to run DEPRECATED
apiVersion: v1
kind: Pod
metadata:
  name: audit-pod
spec:
  containers:
  - name: test-container
    image: nginx
    securityContext:
      runAsNonRoot: false
warn Logs violations and shows warnings but allows pods to run NEW
apiVersion: v1
kind: Pod
metadata:
  name: warn-pod
spec:
  containers:
  - name: test-container
    image: nginx
    securityContext:
      runAsNonRoot: false

Example: Enforcing Pod Security Admission

apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    pod-security.kubernetes.io/enforce: privileged
Note: The pod-security.kubernetes.io/enforce label must be set on the namespace to enforce a policy.
Warning: Ensure that all pods in the namespace comply with the selected policy to avoid runtime issues.

3. Configuring Namespace Labels

Label Key Value Description
pod-security.kubernetes.io/enforce enforce Enforces the specified policy level for all pods in the namespace.
pod-security.kubernetes.io/enforce-version v1.28 Specifies the version of the policy to enforce (default is latest stable).
pod-security.kubernetes.io/audit audit Logs violations but does not block pods from being created.
pod-security.kubernetes.io/audit-version v1.28 Specifies the version of the policy to audit (default is latest stable).
pod-security.kubernetes.io/warn warn Generates warnings for policy violations but allows pods to be created.
pod-security.kubernetes.io/warn-version v1.28 Specifies the version of the policy to warn about (default is latest stable).

Example: Applying Pod Security Labels to a Namespace

apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    pod-security.kubernetes.io/enforce: enforce
    pod-security.kubernetes.io/enforce-version: v1.28
    pod-security.kubernetes.io/audit: audit
    pod-security.kubernetes.io/audit-version: v1.28
    pod-security.kubernetes.io/warn: warn
    pod-security.kubernetes.io/warn-version: v1.28
Note: The pod-security.kubernetes.io/enforce label must be set to enforce for the policy to take effect.
Warning: Ensure that all pods in the namespace comply with the selected policy level to avoid admission rejections.

4. Setting Enforce Level

Level Description Enforcement Behavior Example Configuration
enforce Enforces the policy and rejects pods that violate it. NEW Blocks pod creation if policy is violated.
{
  "enforce": "restricted"
}
audit Logs policy violations but does not block pod creation. Allows pods to be created but logs violations for review.
{
  "audit": "restricted"
}
warn Warns about policy violations without blocking or logging. Does not enforce or log; only displays warnings in logs.
{
  "warn": "restricted"
}

Example: Enforce Level Configuration

apiVersion: v1
kind: Pod
metadata:
  name: example-pod
  annotations:
    pod-security.kubernetes.io/enforce: "restricted"
spec:
  containers:
  - name: example-container
    image: nginx
Note: The enforce level is the most strict and should be used in production environments to ensure compliance with security policies.

5. Setting Audit Level

Level Description Usage
None No events are logged. For environments where audit logging is not required.
Metadata Logs the request metadata, such as user, group, and timestamp. For basic compliance or debugging without sensitive data.
Request Logs the request metadata and the request body (excluding sensitive fields). For detailed tracking of API requests without full payload exposure.
RequestResponse Logs the request metadata and both the request and response bodies (excluding sensitive fields). For full audit trail including responses, useful for compliance and debugging.

Example: Setting Audit Level in Kubernetes

apiVersion: audit.k8s.io/v1
kind: Policy
metadata:
  name: example-policy
rules:
- level: RequestResponse
  users: ["admin"]
  resources:
  - group: ""
    resources: ["pods"]

6. Setting Warn Level

Configuration Value Description
admission.config.k8s.io/warn true Enables warning mode for Pod Security Admission
admission.config.k8s.io/enforce false Disables enforcement mode for Pod Security Admission

Example: Setting Warn Level in a Namespace

apiVersion: v1
kind: Namespace
metadata:
  name: example-namespace
  labels:
    pod-security.kubernetes.io/enforce: "warn"
    pod-security.kubernetes.io/warn: "warn"
Note: In warn mode, Pod Security Admission logs violations but does not reject pods.

7. Controlling Host Namespaces

Field Description Values Notes
hostPID Controls whether pods can share the host PID namespace true / false Defaults to false. Setting to true allows pods to see processes from the host
hostIPC Controls whether pods can share the host IPC namespace true / false Defaults to false. Setting to true allows pods to access host inter-process communication resources
hostNetwork Controls whether pods can use the host network namespace true / false Defaults to false. Setting to true allows pods to bind to host network interfaces

Example: Setting hostNetwork to true in a Pod

apiVersion: v1
kind: Pod
metadata:
  name: host-network-pod
spec:
  hostNetwork: true
  containers:
  - name: nginx
    image: nginx
Note: Enabling host namespaces increases security risks and should be avoided unless necessary for specific use cases like system-level monitoring or network services.

8. Restricting Volume Types

Volume Type Description Security Considerations Configuration
awsElasticBlockStore Represents an EBS volume attached to the kubelet node. Potential for data leakage if not properly secured or restricted. volumeMounts:
- name: ebs-volume
mountPath: /data
azureDisk Represents an Azure Disk volume. Requires proper RBAC and access control to prevent unauthorized access. volumes:
- name: azure-disk
azureDisk:
diskName: my-disk
gcePersistentDisk Represents a GCE PD mounted to the kubelet node. Access control must be enforced via IAM roles and policies. volumes:
- name: gce-pd
gcePersistentDisk:
pdName: my-pd
nfs Represents an NFS mount. Requires secure network configuration and authentication to prevent data exposure. volumes:
- name: nfs-volume
nfs:
server: nfs-server
hostPath Represents a directory on the host node's filesystem. DEPRECATED - Can lead to privilege escalation and host filesystem exposure. volumes:
- name: host-path
hostPath:
path: /etc
emptyDir Represents a temporary directory mounted to the pod. Safe for use but should not be used for persistent storage or sensitive data. volumes:
- name: temp-dir
emptyDir: {}

Example: Restricting Volume Types in Pod Security Admission

apiVersion: v1
kind: Pod
metadata:
  name: restricted-pod
spec:
  containers:
  - name: app-container
    image: nginx
    volumeMounts:
    - name: temp-dir
      mountPath: /app-data
  volumes:
  - name: temp-dir
    emptyDir: {}
Note: The hostPath volume type is often restricted due to its potential for privilege escalation and host filesystem access.

9. Configuring Allowed Capabilities

Capability Description Allowed in PSP Notes
NET_ADMIN Modify network configuration DEPRECATED Replaced by NET_BIND_SERVICE in newer versions
NET_BIND_SERVICE Bind to privileged ports (e.g., < 1024) NEW Used for binding to low ports in containers
SYS_ADMIN Perform administrative operations DEPRECATED Can be replaced with more granular capabilities
SYS_CHROOT Use chroot() system call NEW Allows changing root directory in container

Example: Pod with Allowed Capabilities

apiVersion: v1
kind: Pod
metadata:
  name: example-pod
spec:
  containers:
  - name: example-container
    image: nginx
    securityContext:
      capabilities:
        allow:
        - NET_BIND_SERVICE
        - SYS_CHROOT

10. Migrating from PodSecurityPolicy

Note: PodSecurityPolicy (PSP) was deprecated in Kubernetes 1.21 and removed in 1.25. Migrating to Pod Security Admission is essential for maintaining security policies.
Feature PodSecurityPolicy (PSP) Pod Security Admission
Policy Enforcement enforce, audit, warn enforce, audit, warn
Configuration Cluster-wide via PodSecurityPolicy CRD Namespace-level via pod-security.kubernetes.io annotations
Policy Levels privileged, restricted, baseline privileged, restricted, baseline

Example: Migrating PSP to Pod Security Admission

# Old PSP Configuration
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: restricted
spec:
  privileged: false
  allowPrivilegeEscalation: false
  defaultAllowPrivilegeEscalation: false
  requiredDropCapabilities:
    - ALL
  volumes:
    - 'emptyDir'
    - 'configMap'
    - 'secret'
  hostNetwork: false
  hostIPC: false
  hostPID: false
  runAsUser:
    rule: 'MustRunAsNonRoot'
  seLinux:
    rule: 'RunAsAny'
  supplementalGroups:
    rule: 'MustRunAs'
    ranges:
      - min: 1
        max: 65535
  fsGroup:
    rule: 'MustRunAs'
    ranges:
      - min: 1
        max: 65535
  readOnlyRootFilesystem: false

# New Pod Security Admission Configuration
apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/enforce-version: latest

Migration Steps

  • Review existing PSP policies and their enforcement levels.
  • Define new Pod Security Admission policies using namespace labels or annotations.
  • Update namespaces to apply the new policies via pod-security.kubernetes.io labels.
  • Validate that workloads comply with the new policies using kubectl or admission logs.
  • Gradually migrate workloads to ensure compatibility with new policies.
Warning: Ensure that all namespaces are updated to use Pod Security Admission before removing PSP support from the cluster.

Was this article helpful?