Pod Security Policy Deprecation: In Memoriam
As you probably know by now, PodSecurityPolicy has been deprecated from Kubernetes for over a year, since the release of Kubernetes 1.21. In short PSP was an admission controller that let cluster managers control security by managing pod-specific policy. Like most other admission controllers, PSP could specify requirements one must meet to enter a pod, and deny any requests which don’t meet that requirement. In rare cases, PSP could also modify pod fields, changing requirements for access.
Now, one could say: “That just sounds like RBAC/ABAC!” You wouldn’t be completely wrong, as both fall into the bucket of admission control. However, PSP allowed users to specify the resources running in their cluster along with the settings for the resources. On the other hand, RBAC would simply recognize pods as pods, without context.
One other thing to note is that PSP is not the same as PodSecurityContext, the Kubernetes tool which allows users to specify security contexts and how the pod will run in practice. In fact, one of PSP’s primary capabilities was to inhibit PSC, and constrain it to default security settings. The deprecation of PSP does not affect PodSecurityContext in any way.
But why is PSP leaving?
PSP allowed administrators to control 16 aspects of a pod such as Running of privileged containers, Usage of host namespaces, and Restricting escalation to root privileges, as we’ve discussed before. However, the developers of Kubernetes realized fairly quickly that PSP had some serious usability problems that couldn’t be addressed without making fully system-breaking changes. As Kubernetes developers themselves put it:
The way PSPs are applied to Pods has proven confusing to nearly everyone that has attempted to use them. It is easy to accidentally grant broader permissions than intended, and difficult to inspect which PSP(s) apply in a given situation. The “changing Pod defaults” feature can be handy, but is only supported for certain Pod settings and it’s not obvious when they will or will not apply to your Pod. Without a “dry run” or audit mode, it’s impractical to retrofit PSP to existing clusters safely, and it’s impossible for PSP to ever be enabled by default. |
In short, this means PSPs are difficult and confusing to deploy, even if you’ve hand-crafted policy specifically for your own Kubernetes system. As a result, even the maintainers of Kubernetes are encouraging their users to veer away from PSP as a whole. Instead, they recommend a number of third party authorization tools, listing K-Rail, Kyvervo and Open Policy Agent (OPA) and OPA Gatekeeper.
Third party admission controllers are extremely powerful, and Kubernetes naming them as a solution to PSP issues proves their trust in the growing open-source cloud community. We at Styra are excited that OPA is trusted by platforms like Kubernetes, as we work to reinvent authorization for the cloud-native world.
Why OPA over PSP?
OPA is the de facto policy agent for cloud-native authorization and uses Rego (a declarative language) for policy creation. It provides a means of standardizing policy definition and management throughout the cloud-native technology stack. When combined with Kubernetes, OPA has the capability to enforce guardrails upon an entire system, requiring users’ permissions to match policy at all times.
OPA uses Rego to make policy decisions. Rego is a declarative language, meaning that policy authors can focus on what they want a query to return rather than how queries should be executed. With OPA, developers no longer have to worry about rebuilding specific authorization controls for every single application or Kubernetes cluster in the stack. Furthermore, OPA is applicable across the entire cloud-native tech stack, so organizations can standardize their authorization practice on OPA, with Rego as the common policy authoring language for developers and platform engineers.
As a result, OPA’s popularity continues to grow and is one of the most widely used authorization kits available today, with multiple enterprises like Capital One and Pinterest using it at scale.
Note: Want to see how Styra can help your organization secure Kubernetes environments? Schedule a 20-minute demo to learn about context-based admission control with Styra Declarative Authorization Service (DAS).
What’s Next for Kubernetes: PodSecurity Admission
Kubernetes and SIG Auth have been creating a PSP Replacement Policy, now called PodSecurity Admission, a simplified successor to PSP. According to the original Kubernetes post PSP post, this new form of admission control is created with the understanding that Kubernetes users are probably going to seek external authorization. The documentation states, “PSP’s replacement doesn’t need to be all things to all people,” as PSP previously tried to be.
Instead, PodSecurity Admission was developed in the opposite direction, with simplicity of deployment and adoption being key to the approach. In addition, scalability was a feature Kubernetes hoped to expand on, especially considering their user base. It has soft rollout features to increase ease of deployment, and is configurable to be active by default, unlike PSP. Finally, it can be deactivated partially or entirely to coexist with external admission controllers like OPA.
Altogether, PodSecurity Admission provides three major features to Kubernetes users:
- Setting Default Security Constraints – Pod Security Admission is a non-mutating admission controller, meaning it won’t modify pods before validating them. If you were relying on this aspect of PSP, you will need to either modify your workloads to meet the Pod Security constraints, or use a Mutating Admission Webhook to make those changes.
- Fine-Grained Control over Policy Definition – Pod Security Admission only supports three standard levels. If you require more control over specific constraints, then you will need to use a Validating Admission Webhook to enforce those policies.
- Sub-Namespace Policy Granularity – PodSecurityPolicy lets you bind different policies to different Service Accounts or users, even within a single namespace. This approach has many pitfalls and is not recommended, but if you require this feature anyway you will need to use a third party webhook instead.
OPA: A PodSecurity Admission Competitor… or a Beautiful Partnership?
The question that instantly comes to mind when one hears about PodSecurity Admission is: will this replace OPA? With Kubernetes taking a pole position in the world of cloud-native technology, enforcing authorization natively is something its developers have to keep in mind moving forward. And while PodSecurity Admission is certainly a great tool for authorization, it isn’t up to scratch when it competes with OPA.
OPA has a number of advantages over PodSecurity Admission, most of which can be taken advantage of by any user. First and foremost, OPA is better suited than PodSecurity Admission to enforcing fine-grained authorization across Kubernetes. OPA comes with a custom, declarative policy language called Rego, which can be used across OPA instances to streamline and replicate your policy as code. This policy can take many forms, and can answer, for example, the following queries:
- Which users can access which resources
- Which subnets egress traffic is allowed to
- Which clusters a workload must be deployed to
- Which registries images can be downloaded from
- Which OS capabilities a container can execute with
- Which times of day the system can be accessed at
Even beyond these capabilities, OPA can be used in tandem with PodSecurity Admission, in order to not only take advantage of Kubernetes’ built-in functionality, but to push that functionality to new heights. By using Rego policies, an administrator could meet Kubernetes’ Pod Security Standards in a more declarative manner than before. For example, an administrator could employ the policy Containers: Disallow privilege escalation in order to prevent any user within a specific Kubernetes container from up-leveling their security clearance in regards to that container. Reasons for this policy could be manyfold, most often having to do with lateral mobility and zero trust. When building zero trust into an infrastructure like Kubernetes, declarative policy makes the difference, and can end up saving you time and money.
On a more advanced level, OPA can help with full pod policies, rather than specific containers. One of the most common examples of a pod policy that can be enhanced by OPA is Pod: Prohibit Containers From Sharing HostPID or HostIPC Namespace. As the name suggests, this policy disallows users from accessing the Host Pod ID or the HostIPC namespaces, upleveling security towards zero trust. On a similar note, administrators often also use Pod: Restrict hostPorts to prevent unqualified users from snooping on network traffic. By integrating OPA with both of these policies, you can rest easy knowing your policy is taking precedence over production.
Integrating OPA with your Kubernetes policies is the stepping stone to a more secure network, happier developers, and reduced time to production. With OPA growing daily, so too does its community. This means more support, more ideas, and more enterprise offerings for all users to expand security in the modern cloud-native world.
The following PSS policies can be implemented with OPA and Styra DAS via the latter’s pre-built policy library for Kubernetes:
Containers: Prohibit Privileged Mode
Pod: Restrict hostPorts
Containers: Disallow privilege escalation
Pod: Prohibit Containers From Sharing HostPID or HostIPC Namespace
Containers: Prohibit Insecure Capabilities
Pod: Restrict sysctls used
Containers: Must run as non-root
Pod: Restrict Seccomp Profiles
Pod: Restrict SeLinuxOptions
Try OPA and Styra DAS out – it’s free!
PSP may have deprecated, but your Kubernetes security is very much still alive — let’s keep it that way! To learn how OPA and Styra DAS can help keep your Kubernetes clusters safe, schedule a demo with a Styra Engineer today. The only thing scarier than unsecured Kubernetes is, well… unsecured Kubernetes. Stay safe and happy developing!