paint-brush
Migrating from Pod Security Policies: A Comprehensive Guideby@viachaslaumatsukevich
4,073 reads
4,073 reads

Migrating from Pod Security Policies: A Comprehensive Guide

by Viachaslau MatsukevichSeptember 5th, 2023
Read on Terminal Reader
Read this story w/o Javascript

Too Long; Didn't Read

Transition from Pod Security Policies (PSP) to Pod Security Admission (PSA) in Kubernetes. PSA is native, aligns with standards, but customization is limited. Modernize security with step-by-step guidance.
featured image - Migrating from Pod Security Policies: A Comprehensive Guide
Viachaslau Matsukevich HackerNoon profile picture


Introduction


As Kubernetes continues to mature as the leading container orchestration platform, security remains a paramount concern for organizations deploying containerized applications. Among the fundamental tools in Kubernetes' security arsenal, Pod Security Policies (PSP)once played a pivotal role. PSP allowed administrators to meticulously define and enforce security constraints on Pods, ensuring that only containers meeting specific security standards could operate within the cluster.

However, the landscape of Kubernetes security is evolving rapidly, and it's important to note that PSP has now been deprecated, starting with Kubernetes 1.25 (see link to Kubernetes 1.25 Urgent Release notes). This change stems from various factors, including the complexity of managing and maintaining PSP policies, often leading to operational challenges for users.

In response to the deprecation, organizations are now looking for modern alternatives to PSP, ones that not only address security requirements but also streamline the process of securing workloads inKubernetes.

In this comprehensive guide, we embark on a journey to navigate this shift in Kubernetes security practices, focusing on the transition to Pod Security Admission (PSA). PSA is one of the most robust alternatives available, and this article explores it in-depth. However, it's worth mentioning that two other alternatives, Kyverno and OPA Gatekeeper, will be covered in separate articles within this series.

Throughout this article, you will find detailed instructions for setting up and installing PSA, step-by-step migration guides to transition from PSP to PSA smoothly, and precise commands for transferring existing PSP rules to PSA. Additionally, you will gain the knowledge to assess namespaces for migration readiness using dry-run commands tailored to PSA.

By the end of this guide, you will gain a comprehensive understanding of the strengths and limitations of PSA, equipping you to make an informed decision based on your organization's specific security requirements and Kubernetes environment.

With this guide, you can confidently modernize your Kubernetes security practices, ensuring that your workloads remain protected as you bid farewell to the era of Pod Security Policies.


Pod Security Admission (PSA)

  • PSA Enforces Kubernetes Security Standards: PSA ensures containers adhere to Kubernetes' native security standards, which are defined by the Pod Security Standards. These standards classify security policies into three distinct profiles, each with a different level of restrictiveness:


    • Privileged: The Privileged policy is intentionally open and entirely unrestricted. Typically, this policy targets system- and infrastructure-level workloads managed by trusted users. It is characterized by an absence of restrictions. While allow-by-default mechanisms like Gatekeeper may inherently be Privileged, for deny-by-default mechanisms such as Pod Security Policy (PSP), the Privileged policy should deactivate all restrictions.

    • Baseline: The Baseline policy is designed for easy adoption by common containerized workloads while preventing known privilege escalations. It caters to application operators and developers of non-critical applications.

    • Restricted: The Restricted policy is focused on enforcing rigorous Pod hardening best practices, albeit at the potential expense of some compatibility. It primarily targets operators and developers of security-critical applications, as well as lower-trust users. For a comprehensive list of controls that should be enforced or disallowed under each profile, you can refer to the official documentation.


  • No Direct PSP Rule Transfer: Unlike some other solutions, PSA does not offer a straightforward method for directly migrating or modifying Pod Security Policy (PSP) rules. PSA's primary focus is on validating pods against the established Kubernetes security standards, including the profiles mentioned above.

  • No Mutations: While PSA is effective at validation, it cannot modify or customize pod specifications as PSP could. PSA's main purpose is to enforce predefined Kubernetes security standards and does not include features for altering or mutating pod specifications. It primarily focuses on validating pods against these established standards.


Setup and Installation

Since PSA is a Kubernetes Native component, to make it work, you just need to ensure that the Pod Security Admission (PSA) controller is enabled in your Kubernetes cluster. You can do that by running the following command:


kubectl api-versions | grep admission


Prep Steps for Migration

Assess Namespace Permissions

Control of Pod Security Admission is influenced by namespace labels. This implies that individuals with the capability to update, patch, or create namespaces also have the authority to modify the Pod Security settings for those namespaces. This modification could potentially bypass stricter security policies. Before proceeding, it is essential to verify that namespace permissions are assigned exclusively to trusted and privileged users. It is advisable to refrain from granting these elevated permissions to users who do not require such access. If additional constraints are needed for configuring Pod Security labels on Namespace objects, consider utilizing an admission webhook to enforce those restrictions.

Streamline and Normalize PodSecurityPolicies

Before migrating to Pod Security Admission (PSA), it is beneficial to normalize your PodSecurityPolicies (PSP):


  • Remove Unsupported Fields: Eliminate options not covered by the Pod Security Standards. These options include:


.spec.allowedHostPaths

.spec.allowedFlexVolumes

.spec.allowedCSIDrivers

.spec.forbiddenSysctls

.spec.runtimeClass
  • Eliminate Purely Mutating Fields: Initiate the process by removing fields that solely have a mutating effect and do not impact the validation policy. These fields, as also mentioned in the "Mapping PodSecurityPolicies to Pod Security Standards" reference, include:
.spec.defaultAllowPrivilegeEscalation
.spec.runtimeClass.defaultRuntimeClassName
.metadata.annotations['seccomp.security.alpha.kubernetes.io/defaultProfileName']
.metadata.annotations['apparmor.security.beta.kubernetes.io/defaultProfileName']
.spec.defaultAddCapabilities

Important Note:

Removing these fields may lead to workloads lacking necessary configurations, which could potentially cause operational issues. It is crucial to ensure that workloads can function correctly with the simplified policies.

Determine the Suitable Pod Security Level

When determining the appropriate Pod Security level for your namespace, you have several methods to consider:


By Security Requirements for the Namespace

If you are familiar with the expected access level and security requirements for the namespace, you can select an appropriate Pod Security level based on those specific requirements. This approach is similar to how you would approach security settings in a new cluster.

By Existing PodSecurityPolicies:

Utilize the "Mapping PodSecurityPolicies to Pod Security Standards"reference to map each of your existing Pod Security Policies (PSPs) to a corresponding Pod Security Standard level.
If your PSPs are not originally based on the Pod Security Standards, you may need to make a decision. Choose a Pod Security level that is at least as permissive as your PSPs, or opt for a level that is at least as restrictive. To identify which PSPs are in use for pods within a specific namespace, use the following command:


kubectl get pods -n $NAMESPACE -o jsonpath="{.items[*].metadata.annotations.kubernetes\.io\/psp}" | tr " " "\n" | sort -u

By Existing Pods:

Conduct a dry run and apply the label command from the next section to test both the Baseline and Restricted Pod Security levels. This helps you assess whether these levels are sufficiently permissive for your existing workloads. Choose the least-privileged valid level that aligns with your existing workloads.

It's important to note that the mentioned options are based on existing pods, which may not account for workloads that are not currently running. This includes CronJobs, scale-to-zero workloads, or other workloads that have not yet been deployed.

Testing the Pod Security Level


Once you've determined the Pod Security level for your namespace (except for the Privileged level), it's important to validate the chosen policy. Pod Security offers testing options to ensure a smooth rollout and compliance with security standards.

Dry Run Testing:


Use this method to assess the impact of the selected policy without immediate enforcement.
To perform a dry run, use the following command, which will highlight any existing pods that do not meet the specified policy level:


kubectl label --overwrite ns $NAMESPACE pod-security.kubernetes.io/enforce=$LEVEL

Audit Mode Testing:

Audit mode allows you to record policy violations without enforcing them. Violating pods are logged in the audit records for later review. Enable audit mode with the command:


kubectl label --overwrite ns $NAMESPACE pod-security.kubernetes.io/audit=$LEVEL


If unexpected policy violations arise during testing, you can:


  • Update non-compliant workloads to align with the policy.
  • Adjust the Pod Security level for the namespace if necessary to accommodate your workload requirements.


Enforcing the Pod Security Level

Once you are confident that the selected Pod Security level is appropriate for your namespace, you can proceed to enforce it. This step ensures that the desired security standards are actively applied to your workloads within the namespace.


To enforce the desired Pod Security level on the namespace, use the following command:

kubectl label --overwrite ns $NAMESPACE pod-security.kubernetes.io/enforce=$LEVEL

Executing this command will activate and enforce the specified Pod Security level, enhancing the security posture of your namespace.


Bypassing PSP

To effectively bypass PodSecurityPolicy at the namespace level, you can bind a fully privileged Pod Security Policy (PSP) to all service accounts in the namespace. This process ensures that pods within the namespace are no longer subjected to modifications or restrictions imposed by PodSecurityPolicy. You can do that at a cluster level or at an individual namespace level.

Cluster-Scoped Setup (Needed Only Once for the whole cluster):

Create a fully privileged Pod Security Policy (PSP) by applying a YAML configuration file, such as privileged-psp.yaml. This PSP should grant all necessary privileges to pods and create a cluster role named privileged-psp to allow the use of Pod Security Policies (PSPs) and associate it with the privileged PSP:


kubectl apply -f privileged-psp.yaml
kubectl create clusterrole privileged-psp --verb use --resource podsecuritypolicies.policy --resource-name privileged

Per-Namespace Disablement:

Create a role binding in the target namespace to associate the privileged-psp cluster role with the system:serviceaccounts:$NAMESPACE group. This binding effectively grants all service accounts within the namespace access to the fully privileged PSP, bypassing PodSecurityPolicy:


kubectl create -n $NAMESPACE rolebinding disable-psp --clusterrole privileged-psp --group system:serviceaccounts:$NAMESPACE


With this setup, the privileged PSP is non-mutating, and the PodSecurityPolicy admission controller always prioritizes non-mutating PSPs. As a result, pods in this namespace will no longer be modified or restricted by PodSecurityPolicy.


One advantage of this approach is its reversibility. If any issues arise, you can easily roll back the change by deleting the RoleBinding associated with disabling PodSecurityPolicy. Ensure that pre-existing Pod Security Policies remain in place during this process.

Undo PodSecurityPolicy Disablement:

To revert the PodSecurityPolicy disablement for the namespace, simply delete the RoleBinding created earlier:

kubectl delete -n $NAMESPACE rolebinding disable-psp

Revisit Namespace Creation Processes

With existing namespaces updated to enforce Pod Security Admission, it's essential to review and update your processes and policies for creating new namespaces. This ensures that new namespaces are configured with an appropriate Pod Security profile from the outset.
Consider the following steps to enhance namespace creation processes:


  1. Adjust Namespace Creation Policies: Update your organization's policies and procedures for creating new namespaces to include the selection and application of the desired Pod Security level. Ensure that security standards are established right from the creation stage.

  2. Static Configuration: You can statically configure the Pod Security admission controller to define default enforcement, audit, and/or warning levels for unlabeled namespaces. This approach ensures that namespaces lacking explicit Pod Security labels still adhere to your specified security standards by default.


    By revisiting your namespace creation processes, you can seamlessly integrate Pod Security standards into your Kubernetes environment and maintain a consistent and secure approach across all namespaces, old and new.


Disable PodSecurityPolicy


Once you are confident that the PodSecurityPolicy (PSP) admission controller is no longer needed and that Pod Security Admission (PSA) has been successfully implemented and validated, you can proceed to disable the PSP admission controller.

Here are the steps to disable the PSP admission controller:

Modify kube-apiserver Configuration:


  • Open the configuration file for your kube-apiserver, typically located at /etc/kubernetes/manifests/kube-apiserver.yaml.
  • Add the --disable-admission-plugins flag to disable the PSP admission controller. Ensure that it's removed from the list of active admission plugins.
kube-apiserver --disable-admission-plugins=PodSecurityPolicy
  • Save the configuration file.

Restart kube-apiserver:

  • Restart the kube-apiserver to apply the changes. You can usually achieve this by restarting the Kubernetes control plane or the kube-apiserver pod itself.
systemctl restart kubelet

Verification:

  • Ensure that the PSP admission controller is disabled by checking the kube-apiserver logs or its status.

After sufficient "soak time" to be confident that you won't need to roll back to PSPs, proceed to the next step.

Cleanup PSP Resources:

With the PSP admission controller disabled and PSA in place, you can safely delete your existing PodSecurityPolicies, as well as any associated Roles, ClusterRoles, RoleBindings, and ClusterRoleBindings.


kubectl delete podsecuritypolicies --all
kubectl delete roles,clusterroles,rolebindings,clusterrolebindings --selector=rbac.authorization.kubernetes.io/autoupdate=true


This cleanup step ensures that there are no residual PSP configurations in your cluster.

By deactivating the PSP admission controller and eliminating PSP-related resources, you simplify your cluster's security architecture, completing the transition to Pod Security Admission.




Summary


In this comprehensive guide, we've explored the essential steps and considerations for smoothly transitioning your Kubernetes cluster's security framework from Pod Security Policies (PSP) to Pod Security Admission (PSA). This migration ensures that your workloads continue to run securely while aligning with Kubernetes' evolving security standards.

Pros and Cons of using Pod Security Admission (PSA)


Pros:

  • Native Kubernetes Component: PSA is an integral part of Kubernetes, eliminating the need for third-party tool installations. It leverages the platform's built-in security features.
  • Enforces Kubernetes Standards: PSA aligns with Kubernetes' native security standards, ensuring compliance with the platform's best practices.

Cons:

  • Limited Customization: PSA may not provide the same level of customization as PSP, especially for complex security policies that require mutation of pod specs.
  • Retrofitting Required: Existing workloads must be updated to include security context settings, which may require modification of YAML files.



This guide equips you with the knowledge and steps required to migrate confidently from PSP to PSA, ensuring a secure and efficient transition while safeguarding your Kubernetes workloads. Stay tuned for upcoming articles, where I will explore alternative migration paths to Kyverno and OPA Gatekeeper.