Arun Shah

Securing Workloads with Kubernetes Pod Security

Admission

Securing Workloads with Kubernetes Pod Security Admission (PSA)

Ensuring that Pods running in your Kubernetes cluster adhere to security best practices is fundamental to maintaining a secure environment. For years, PodSecurityPolicy (PSP) was the primary mechanism for enforcing these constraints. However, PSPs proved complex to manage, difficult to apply consistently, and had usability challenges.

Important: PodSecurityPolicy (PSP) was deprecated in Kubernetes v1.21 and removed entirely in v1.25. If you are running a modern Kubernetes cluster, you should not be using PSPs.

The successor to PSP is the built-in Pod Security Admission (PSA) controller, combined with the defined Pod Security Standards (PSS). PSA offers a simpler, more standardized, and easier-to-manage approach to enforcing Pod security baselines at the namespace level.

This guide explains the concepts behind PSA and PSS, provides practical examples, and outlines best practices for securing your workloads using the current Kubernetes standard. We’ll briefly cover PSPs for historical context.

PodSecurityPolicy (PSP): A Look Back (Deprecated)

Before PSA, PodSecurityPolicy was a cluster-level resource that defined a set of conditions a Pod must meet to be accepted into the cluster (or mutated). PSPs controlled security-sensitive aspects like:

While powerful, PSPs required complex RBAC configurations (binding Policies to Service Accounts via Roles/ClusterRoles) and often led to confusing authorization errors if not perfectly configured.

Example Restricted PSP (Historical Context Only):

# --- DEPRECATED: Do not use on K8s v1.25+ ---
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: restricted-psp-example
  annotations:
    seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'runtime/default'
    seccomp.security.alpha.kubernetes.io/defaultProfileName:  'runtime/default'
spec:
  privileged: false # Disallow privileged containers
  allowPrivilegeEscalation: false # Prevent gaining more privileges
  requiredDropCapabilities: # Drop all capabilities
    - ALL
  # Allow specific volume types only
  volumes:
    - 'configMap'
    - 'emptyDir'
    - 'projected'
    - 'secret'
    - 'downwardAPI'
    - 'persistentVolumeClaim'
  hostNetwork: false # Disallow host network access
  hostIPC: false
  hostPID: false
  runAsUser:
    rule: 'MustRunAsNonRoot' # Require non-root user
  seLinux:
    rule: 'RunAsAny' # SELinux context (adjust as needed)
  supplementalGroups:
    rule: 'MustRunAs'
    ranges: # Define allowed group ID ranges
      - min: 1
        max: 65535
  fsGroup:
    rule: 'MustRunAs'
    ranges:
      - min: 1
        max: 65535
  readOnlyRootFilesystem: false # Optional: Could be set to true

Key takeaway: PSPs offered granular control but required significant effort to implement correctly across a cluster, leading to their deprecation.

The Modern Approach: Pod Security Admission (PSA) & Standards (PSS)

PSA is a built-in admission controller (enabled by default in modern Kubernetes versions) that enforces security constraints based on the Pod Security Standards. It simplifies Pod security by providing predefined profiles and applying them at the namespace level.

Pod Security Standards (PSS)

These are three predefined policies, offering tiered levels of security:

  1. privileged: Unrestricted policy, providing the widest possible permissions. Allows for known privilege escalations. Should only be used for trusted, system-level workloads managed by privileged users. Avoid for general application workloads.
  2. baseline: A minimally restrictive policy preventing known privilege escalations while ensuring broad application compatibility. It disallows hostNetwork, privileged containers, hostPath volumes, etc., but is less strict than restricted on things like capabilities or user IDs. A good default starting point for many applications.
  3. restricted: A heavily restricted policy following current Pod hardening best practices. It enforces non-root execution, drops most capabilities, restricts volume types, requires secure seccomp profiles, etc. Offers the best security posture but may require application modifications to comply. The recommended standard for most application workloads.

Each standard defines specific controls related to fields in the Pod spec and securityContext. You can find the detailed controls for each standard in the official Kubernetes documentation.

Pod Security Admission (PSA) Controller

The PSA controller enforces the PSS profiles based on labels applied to Namespaces. This namespace-level configuration makes it much easier to manage than the complex RBAC required for PSPs.

Configuration via Namespace Labels:

You apply labels to a Namespace to configure the PSA mode for a specific PSS profile:

Example Namespace Configuration:

This example enforces the restricted standard, audits against baseline, and warns against baseline violations for Pods created in the my-secure-app namespace.

apiVersion: v1
kind: Namespace
metadata:
  name: my-secure-app
  labels:
    # Enforce: Reject Pods violating the 'restricted' standard (latest version)
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/enforce-version: latest

    # Audit: Log audit events for Pods violating the 'baseline' standard
    pod-security.kubernetes.io/audit: baseline
    pod-security.kubernetes.io/audit-version: latest

    # Warn: Send warnings to users creating Pods violating the 'baseline' standard
    pod-security.kubernetes.io/warn: baseline
    pod-security.kubernetes.io/warn-version: latest

Modes & Rollout: You can use different modes simultaneously. A common strategy is to start with warn or audit mode for a stricter profile (like restricted) to identify non-compliant workloads without breaking them, then gradually move to enforce mode once workloads are updated.

Best Practices for Pod Security Admission

  1. Use PSA, Not PSPs: Ensure you are using PSA on supported Kubernetes versions (v1.23+ recommended, PSP removed in v1.25). Disable the PSP admission controller if migrating.
  2. Default to restricted: Aim to apply the restricted PSS profile using enforce mode to all application namespaces where possible. This provides the strongest security baseline.
  3. Use baseline as a Fallback: If restricted breaks applications initially, apply the baseline profile in enforce mode as a minimum standard while working towards restricted compliance. Use warn: restricted or audit: restricted to identify gaps.
  4. Reserve privileged for Exceptions: Only use the privileged profile for specific, trusted system workloads (e.g., monitoring agents, CSI drivers) in dedicated, secured namespaces. Document and tightly control access to these namespaces.
  5. Apply Policies Per Namespace: Leverage the namespace-level labeling for granular control. Different namespaces can have different enforcement levels based on workload sensitivity and trust.
  6. Pin Versions: Use the -version label (e.g., pod-security.kubernetes.io/enforce-version: v1.28) to pin policies to a specific Kubernetes minor version’s standard. This prevents unexpected behavior when the cluster is upgraded and the standards potentially change. Use latest only if you intend to automatically adopt new standard versions upon upgrade.
  7. Audit and Warn During Rollout: Use audit and warn modes to identify non-compliant workloads before enabling enforce mode, preventing disruption. Monitor audit logs.
  8. Exemptions: PSA allows exempting specific users, runtime classes, or namespaces from enforcement if absolutely necessary, but use exemptions sparingly and with strong justification.
  9. Combine with Other Security Tools: PSA is one layer. Combine it with Network Policies, RBAC, securityContext settings within Pods (which PSA validates), image scanning, and runtime security tools for defense-in-depth.

Migrating from PSP to PSA

  1. Understand PSS Profiles: Familiarize yourself with the controls defined in the baseline and restricted Pod Security Standards.
  2. Analyze Existing Workloads: Identify which workloads would violate the baseline or restricted standards. Tools like kubectl-psp-migrate or manual review can help.
  3. Enable PSA Controller: Ensure the PodSecurity admission plugin is enabled in your kube-apiserver configuration (usually enabled by default in v1.23+).
  4. Apply PSA Labels (Audit/Warn Mode): Apply appropriate PSS labels (e.g., audit: restricted, warn: restricted) to your namespaces without enabling enforce yet. Monitor audit logs and warnings for non-compliant Pods.
  5. Remediate Workloads: Update non-compliant Pod specs (e.g., add securityContext, remove privileged settings) to meet the target PSS profile (baseline or restricted).
  6. Enable Enforcement: Once workloads are compliant, change the namespace label mode from audit/warn to enforce (e.g., enforce: restricted).
  7. Disable PSP: Once PSA is fully enforced across relevant namespaces, disable the PodSecurityPolicy admission controller in the kube-apiserver configuration and remove all PSP and related RBAC resources (Roles, ClusterRoles, RoleBindings, ClusterRoleBindings granting use permission on PSPs).

Conclusion: Simplified and Standardized Pod Security

Pod Security Admission and Pod Security Standards represent a significant improvement over the deprecated PodSecurityPolicy mechanism. By providing clear, tiered standards (privileged, baseline, restricted) and a straightforward namespace-level enforcement model via labels, PSA makes it easier for cluster administrators and developers to apply consistent security baselines across their workloads. While migrating requires analysis and potential workload adjustments, adopting PSA/PSS is crucial for securing modern Kubernetes clusters effectively and aligning with current best practices.

References

  1. Kubernetes Documentation - Pod Security Admission: https://kubernetes.io/docs/concepts/security/pod-security-admission/
  2. Kubernetes Documentation - Pod Security Standards: https://kubernetes.io/docs/concepts/security/pod-security-standards/
  3. Kubernetes Documentation - Migrating from PodSecurityPolicy: https://kubernetes.io/docs/tasks/configure-pod-container/migrate-from-psp/
  4. Kubernetes Blog: PodSecurityPolicy Deprecation: Past, Present, and Future: https://kubernetes.io/blog/2021/04/06/podsecuritypolicy-deprecation-past-present-and-future/

Comments